diff --git a/src/Common/Commands.Common/Commands.Common.csproj b/src/Common/Commands.Common/Commands.Common.csproj
index 10af73bb0fbb..3327be6458bd 100644
--- a/src/Common/Commands.Common/Commands.Common.csproj
+++ b/src/Common/Commands.Common/Commands.Common.csproj
@@ -171,6 +171,7 @@
+
diff --git a/src/Common/Commands.Common/DiagnosticsHelper.cs b/src/Common/Commands.Common/DiagnosticsHelper.cs
new file mode 100644
index 000000000000..3b5a5007969c
--- /dev/null
+++ b/src/Common/Commands.Common/DiagnosticsHelper.cs
@@ -0,0 +1,127 @@
+// ----------------------------------------------------------------------------------
+//
+// Copyright Microsoft Corporation
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ----------------------------------------------------------------------------------
+
+using Microsoft.WindowsAzure.Commands.Common.Properties;
+using System;
+using System.Collections;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using Newtonsoft.Json;
+
+namespace Microsoft.WindowsAzure.Commands.Utilities.Common
+{
+ public static class DiagnosticsHelper
+ {
+ private static string XmlNamespace = "http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration";
+ private static string EncodedXmlCfg = "xmlCfg";
+ private static string StorageAccount = "storageAccount";
+ private static string Path = "path";
+ private static string ExpandResourceDirectory = "expandResourceDirectory";
+ private static string LocalResourceDirectory = "localResourceDirectory";
+ private static string StorageAccountNameTag = "storageAccountName";
+ private static string StorageAccountKeyTag = "storageAccountKey";
+ private static string StorageAccountEndPointTag = "storageAccountEndPoint";
+
+ public static string GetJsonSerializedPublicDiagnosticsConfigurationFromFile(string configurationPath,
+ string storageAccountName)
+ {
+ return
+ JsonConvert.SerializeObject(
+ DiagnosticsHelper.GetPublicDiagnosticsConfigurationFromFile(configurationPath, storageAccountName));
+ }
+
+ public static Hashtable GetPublicDiagnosticsConfigurationFromFile(string configurationPath, string storageAccountName)
+ {
+ using (StreamReader reader = new StreamReader(configurationPath))
+ {
+ return GetPublicDiagnosticsConfiguration(reader.ReadToEnd(), storageAccountName);
+ }
+ }
+
+ public static Hashtable GetPublicDiagnosticsConfiguration(string config, string storageAccountName)
+ {
+ // find the element and extract it
+ int wadCfgBeginIndex = config.IndexOf("");
+ if (wadCfgBeginIndex == -1)
+ {
+ throw new ArgumentException(Resources.IaasDiagnosticsBadConfigNoWadCfg);
+ }
+
+ int wadCfgEndIndex = config.IndexOf("");
+ if (wadCfgEndIndex == -1)
+ {
+ throw new ArgumentException(Resources.IaasDiagnosticsBadConfigNoEndWadCfg);
+ }
+
+ if (wadCfgEndIndex <= wadCfgBeginIndex)
+ {
+ throw new ArgumentException(Resources.IaasDiagnosticsBadConfigNoMatchingWadCfg);
+ }
+
+ string encodedConfiguration = Convert.ToBase64String(
+ Encoding.UTF8.GetBytes(
+ config.Substring(
+ wadCfgBeginIndex, wadCfgEndIndex + "".Length - wadCfgBeginIndex).ToCharArray()));
+
+ // Now extract the local resource directory element
+ XmlDocument doc = new XmlDocument();
+ XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
+ ns.AddNamespace("ns", XmlNamespace);
+ doc.LoadXml(config);
+ var node = doc.SelectSingleNode("//ns:LocalResourceDirectory", ns);
+ string localDirectory = (node != null && node.Attributes != null) ? node.Attributes[Path].Value : null;
+ string localDirectoryExpand = (node != null && node.Attributes != null)
+ ? node.Attributes["expandEnvironment"].Value
+ : null;
+ if (localDirectoryExpand == "0")
+ {
+ localDirectoryExpand = "false";
+ }
+ if (localDirectoryExpand == "1")
+ {
+ localDirectoryExpand = "true";
+ }
+
+ var hashTable = new Hashtable();
+ hashTable.Add(EncodedXmlCfg, encodedConfiguration);
+ hashTable.Add(StorageAccount, storageAccountName);
+ if (!string.IsNullOrEmpty(localDirectory))
+ {
+ var localDirectoryHashTable = new Hashtable();
+ localDirectoryHashTable.Add(Path, localDirectory);
+ localDirectoryHashTable.Add(ExpandResourceDirectory, localDirectoryExpand);
+ hashTable.Add(LocalResourceDirectory, localDirectoryHashTable);
+ }
+
+ return hashTable;
+ }
+
+ public static string GetJsonSerializedPrivateDiagnosticsConfiguration(string storageAccountName,
+ string storageKey, string endpoint)
+ {
+ return JsonConvert.SerializeObject(GetPrivateDiagnosticsConfiguration( storageAccountName, storageKey, endpoint));
+ }
+
+ public static Hashtable GetPrivateDiagnosticsConfiguration(string storageAccountName, string storageKey, string endpoint)
+ {
+ var hashTable = new Hashtable();
+ hashTable.Add(StorageAccountNameTag, storageAccountName);
+ hashTable.Add(StorageAccountKeyTag, storageKey);
+ hashTable.Add(StorageAccountEndPointTag, endpoint);
+ return hashTable;
+ }
+ }
+}
diff --git a/src/Common/Commands.Common/Properties/Resources.Designer.cs b/src/Common/Commands.Common/Properties/Resources.Designer.cs
index 1b2caf4f5f8e..a10815c4434d 100644
--- a/src/Common/Commands.Common/Properties/Resources.Designer.cs
+++ b/src/Common/Commands.Common/Properties/Resources.Designer.cs
@@ -978,6 +978,33 @@ public static string GlobalSettingsManager_Load_PublishSettingsNotFound {
}
}
+ ///
+ /// Looks up a localized string similar to Cannot find the WadCfg end element in the config..
+ ///
+ public static string IaasDiagnosticsBadConfigNoEndWadCfg {
+ get {
+ return ResourceManager.GetString("IaasDiagnosticsBadConfigNoEndWadCfg", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to WadCfg start element in the config is not matching the end element..
+ ///
+ public static string IaasDiagnosticsBadConfigNoMatchingWadCfg {
+ get {
+ return ResourceManager.GetString("IaasDiagnosticsBadConfigNoMatchingWadCfg", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Cannot find the WadCfg element in the config..
+ ///
+ public static string IaasDiagnosticsBadConfigNoWadCfg {
+ get {
+ return ResourceManager.GetString("IaasDiagnosticsBadConfigNoWadCfg", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to iisnode.dll.
///
diff --git a/src/Common/Commands.Common/Properties/Resources.resx b/src/Common/Commands.Common/Properties/Resources.resx
index 7616e8b49007..c3e3784a3713 100644
--- a/src/Common/Commands.Common/Properties/Resources.resx
+++ b/src/Common/Commands.Common/Properties/Resources.resx
@@ -1443,4 +1443,13 @@ The file needs to be a PowerShell script (.ps1 or .psm1).
Cannot delete '{0}': {1}
{0} is the path of a file, {1} is an error message
+
+ Cannot find the WadCfg end element in the config.
+
+
+ WadCfg start element in the config is not matching the end element.
+
+
+ Cannot find the WadCfg element in the config.
+
\ No newline at end of file
diff --git a/src/ResourceManager/Compute/Commands.Compute/Commands.Compute.csproj b/src/ResourceManager/Compute/Commands.Compute/Commands.Compute.csproj
index 076a768a6a8a..3c77972a2462 100644
--- a/src/ResourceManager/Compute/Commands.Compute/Commands.Compute.csproj
+++ b/src/ResourceManager/Compute/Commands.Compute/Commands.Compute.csproj
@@ -121,6 +121,9 @@
..\..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
True
+
+ ..\..\..\packages\Microsoft.WindowsAzure.Management.Storage.5.1.1\lib\net40\Microsoft.WindowsAzure.Management.Storage.dll
+
@@ -161,6 +164,9 @@
+
+
+
diff --git a/src/ResourceManager/Compute/Commands.Compute/Common/ConstantStringTypes.cs b/src/ResourceManager/Compute/Commands.Compute/Common/ConstantStringTypes.cs
index 74d022e5c868..a46ca676e876 100644
--- a/src/ResourceManager/Compute/Commands.Compute/Common/ConstantStringTypes.cs
+++ b/src/ResourceManager/Compute/Commands.Compute/Common/ConstantStringTypes.cs
@@ -70,6 +70,7 @@ public static class ProfileNouns
public const string VirtualMachineExtension = "AzureVMExtension";
public const string VirtualMachineCustomScriptExtension = "AzureVMCustomScriptExtension";
public const string VirtualMachineAccessExtension = "AzureVMAccessExtension";
+ public const string VirtualMachineDiagnosticsExtension = "AzureVMDiagnosticsExtension";
public const string VirtualMachineExtensionImage = "AzureVMExtensionImage";
public const string VirtualMachineExtensionImageVersion = "AzureVMExtensionImageVersion";
public const string VirtualMachineExtensionImageType = "AzureVMExtensionImageType";
diff --git a/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/GetAzureVMDiagnosticsExtension.cs b/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/GetAzureVMDiagnosticsExtension.cs
new file mode 100644
index 000000000000..d0c221988dca
--- /dev/null
+++ b/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/GetAzureVMDiagnosticsExtension.cs
@@ -0,0 +1,88 @@
+// ----------------------------------------------------------------------------------
+//
+// Copyright Microsoft Corporation
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ----------------------------------------------------------------------------------
+
+using System.Linq;
+using System.Management.Automation;
+using Microsoft.Azure.Commands.Compute.Common;
+using Microsoft.Azure.Commands.Compute.Models;
+using Microsoft.Azure.Management.Compute;
+using Microsoft.Azure.Management.Compute.Models;
+
+namespace Microsoft.Azure.Commands.Compute
+{
+ [Cmdlet(
+ VerbsCommon.Get,
+ ProfileNouns.VirtualMachineDiagnosticsExtension),
+ OutputType(
+ typeof(PSVirtualMachineExtension))]
+ public class GetAzureVMDiagnosticsExtensionCommand : VirtualMachineExtensionBaseCmdlet
+ {
+ [Parameter(
+ Mandatory = true,
+ Position = 0,
+ ValueFromPipelineByPropertyName = true,
+ HelpMessage = "The resource group name.")]
+ [ValidateNotNullOrEmpty]
+ public string ResourceGroupName { get; set; }
+
+ [Alias("ResourceName")]
+ [Parameter(
+ Mandatory = true,
+ Position = 1,
+ ValueFromPipelineByPropertyName = true,
+ HelpMessage = "The virtual machine name.")]
+ [ValidateNotNullOrEmpty]
+ public string VMName { get; set; }
+
+ [Alias("ExtensionName")]
+ [Parameter(
+ Mandatory = true,
+ Position = 2,
+ ValueFromPipelineByPropertyName = true,
+ HelpMessage = "Extension Name.")]
+ [ValidateNotNullOrEmpty]
+ public string Name { get; set; }
+
+ [Parameter(
+ Position = 3,
+ ValueFromPipelineByPropertyName = true,
+ HelpMessage = "To show the status.")]
+ [ValidateNotNullOrEmpty]
+ public SwitchParameter Status { get; set; }
+
+ public override void ExecuteCmdlet()
+ {
+ base.ExecuteCmdlet();
+
+ ExecuteClientAction(() =>
+ {
+ VirtualMachineExtensionGetResponse virtualMachineExtensionGetResponse = null;
+ if (Status.IsPresent)
+ {
+ virtualMachineExtensionGetResponse =
+ this.VirtualMachineExtensionClient.GetWithInstanceView(this.ResourceGroupName,
+ this.VMName, this.Name);
+ }
+ else
+ {
+ virtualMachineExtensionGetResponse = this.VirtualMachineExtensionClient.Get(this.ResourceGroupName,
+ this.VMName, this.Name);
+ }
+
+ var returnedExtension = virtualMachineExtensionGetResponse.ToPSVirtualMachineExtension(this.ResourceGroupName);
+ WriteObject(returnedExtension);
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/RemoveAzureVMDiagnosticsExtension.cs b/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/RemoveAzureVMDiagnosticsExtension.cs
new file mode 100644
index 000000000000..16af517fb880
--- /dev/null
+++ b/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/RemoveAzureVMDiagnosticsExtension.cs
@@ -0,0 +1,66 @@
+// ----------------------------------------------------------------------------------
+//
+// Copyright Microsoft Corporation
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ----------------------------------------------------------------------------------
+
+using System;
+using System.Management.Automation;
+using Microsoft.Azure.Commands.Compute.Common;
+using Microsoft.Azure.Management.Compute;
+using Microsoft.WindowsAzure.Commands.ServiceManagement.Model;
+
+namespace Microsoft.Azure.Commands.Compute
+{
+ [Cmdlet(
+ VerbsCommon.Remove,
+ ProfileNouns.VirtualMachineDiagnosticsExtension)]
+ public class RemoveAzureVMDiagnosticsExtensionCommand : VirtualMachineExtensionBaseCmdlet
+ {
+ [Parameter(
+ Mandatory = true,
+ Position = 0,
+ ValueFromPipelineByPropertyName = true,
+ HelpMessage = "The resource group name.")]
+ [ValidateNotNullOrEmpty]
+ public string ResourceGroupName { get; set; }
+
+ [Alias("ResourceName")]
+ [Parameter(
+ Mandatory = true,
+ Position = 1,
+ ValueFromPipelineByPropertyName = true,
+ HelpMessage = "The virtual machine name.")]
+ [ValidateNotNullOrEmpty]
+ public string VMName { get; set; }
+
+ [Alias("ExtensionName")]
+ [Parameter(
+ Mandatory = true,
+ Position = 2,
+ ValueFromPipelineByPropertyName = true,
+ HelpMessage = "Extension Name.")]
+ [ValidateNotNullOrEmpty]
+ public string Name { get; set; }
+
+ public override void ExecuteCmdlet()
+ {
+ base.ExecuteCmdlet();
+
+ ExecuteClientAction(() =>
+ {
+ var op = this.VirtualMachineExtensionClient.Delete(this.ResourceGroupName, this.VMName,
+ this.Name);
+ WriteObject(op);
+ });
+ }
+ }
+}
diff --git a/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/SetAzureVMDiagnosticsExtension.cs b/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/SetAzureVMDiagnosticsExtension.cs
new file mode 100644
index 000000000000..9e6839b7fbcd
--- /dev/null
+++ b/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/SetAzureVMDiagnosticsExtension.cs
@@ -0,0 +1,224 @@
+// ----------------------------------------------------------------------------------
+//
+// Copyright Microsoft Corporation
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ----------------------------------------------------------------------------------
+
+using System;
+using System.Management.Automation;
+using Microsoft.Azure.Commands.Compute.Common;
+using Microsoft.Azure.Common.Authentication;
+using Microsoft.Azure.Common.Authentication.Models;
+using Microsoft.Azure.Management.Compute;
+using Microsoft.Azure.Management.Compute.Models;
+using Microsoft.WindowsAzure.Commands.Common.Storage;
+using Microsoft.WindowsAzure.Commands.Utilities.Common;
+using Microsoft.WindowsAzure.Management.Storage;
+using Newtonsoft.Json;
+
+namespace Microsoft.Azure.Commands.Compute
+{
+ [Cmdlet(
+ VerbsCommon.Set,
+ ProfileNouns.VirtualMachineDiagnosticsExtension)]
+ public class SetAzureVMDiagnosticsExtensionCommand : VirtualMachineExtensionBaseCmdlet
+ {
+ private string publicConfiguration;
+ private string privateConfiguration;
+ private string storageKey;
+ private const string VirtualMachineExtension = "Microsoft.Compute/virtualMachines/extensions";
+ private const string IaaSDiagnosticsExtension = "IaaSDiagnostics";
+ private const string ExtensionPublisher = "Microsoft.Azure.Diagnostics";
+ private StorageManagementClient storageClient;
+
+ [Parameter(
+ Mandatory = true,
+ Position = 0,
+ ValueFromPipelineByPropertyName = true,
+ HelpMessage = "The resource group name.")]
+ [ValidateNotNullOrEmpty]
+ public string ResourceGroupName { get; set; }
+
+ [Alias("ResourceName")]
+ [Parameter(
+ Mandatory = true,
+ Position = 1,
+ ValueFromPipelineByPropertyName = true,
+ HelpMessage = "The virtual machine name.")]
+ [ValidateNotNullOrEmpty]
+ public string VMName { get; set; }
+
+ [Parameter(
+ Mandatory = true,
+ Position = 2,
+ ValueFromPipelineByPropertyName = false,
+ HelpMessage = "XML Diagnostics Configuration")]
+ [ValidateNotNullOrEmpty]
+ public string DiagnosticsConfigurationPath
+ {
+ get;
+ set;
+ }
+
+ [Parameter(
+ Mandatory = true,
+ Position = 3,
+ ValueFromPipelineByPropertyName = true,
+ HelpMessage = "The storage connection context")]
+ [ValidateNotNullOrEmpty]
+ public AzureStorageContext StorageContext
+ {
+ get;
+ set;
+ }
+
+ [Parameter(
+ Position = 4,
+ ValueFromPipelineByPropertyName = true,
+ HelpMessage = "The location.")]
+ [ValidateNotNullOrEmpty]
+ public string Location { get; set; }
+
+ [Alias("ExtensionName")]
+ [Parameter(
+ Mandatory = true,
+ Position = 5,
+ ValueFromPipelineByPropertyName = true,
+ HelpMessage = "Extension Name.")]
+ [ValidateNotNullOrEmpty]
+ public string Name { get; set; }
+
+ public string StorageAccountName
+ {
+ get
+ {
+ return this.StorageContext.StorageAccountName;
+ }
+ }
+
+ public string Endpoint
+ {
+ get
+ {
+ return "https://" + this.StorageContext.EndPointSuffix;
+ }
+ }
+
+ public string StorageKey
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(this.storageKey))
+ {
+ this.storageKey = GetStorageKey();
+ }
+
+ return this.storageKey;
+ }
+ }
+
+ public string PublicConfiguration
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(this.publicConfiguration))
+ {
+ this.publicConfiguration =
+ DiagnosticsHelper.GetJsonSerializedPublicDiagnosticsConfigurationFromFile(
+ this.DiagnosticsConfigurationPath, this.StorageAccountName);
+ }
+
+ return this.publicConfiguration;
+ }
+ }
+
+ public string PrivateConfiguration
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(this.privateConfiguration))
+ {
+ this.privateConfiguration = DiagnosticsHelper.GetJsonSerializedPrivateDiagnosticsConfiguration(this.StorageAccountName, this.StorageKey,
+ this.Endpoint);
+ }
+
+ return this.privateConfiguration;
+ }
+ }
+
+ public StorageManagementClient StorageClient
+ {
+ get
+ {
+ if (this.storageClient == null)
+ {
+ this.storageClient = AzureSession.ClientFactory.CreateClient(
+ Profile.Context, AzureEnvironment.Endpoint.ServiceManagement);
+ }
+
+ return this.storageClient;
+ }
+ }
+
+ internal void ExecuteCommand()
+ {
+ base.ExecuteCmdlet();
+
+ ExecuteClientAction(() =>
+ {
+ var parameters = new VirtualMachineExtension
+ {
+ Location = this.Location,
+ Name = this.Name,
+ Type = VirtualMachineExtension,
+ Settings = this.PublicConfiguration,
+ ProtectedSettings = this.PrivateConfiguration,
+ Publisher = ExtensionPublisher,
+ ExtensionType = IaaSDiagnosticsExtension,
+ TypeHandlerVersion = "1.4"
+ };
+
+ var op = this.VirtualMachineExtensionClient.CreateOrUpdate(
+ this.ResourceGroupName,
+ this.VMName,
+ parameters);
+
+ WriteObject(op);
+ });
+ }
+
+ protected string GetStorageKey()
+ {
+ string storageKey = string.Empty;
+
+ if (!string.IsNullOrEmpty(StorageAccountName))
+ {
+ var storageAccount = this.StorageClient.StorageAccounts.Get(StorageAccountName);
+ if (storageAccount != null)
+ {
+ var keys = this.StorageClient.StorageAccounts.GetKeys(StorageAccountName);
+ if (keys != null)
+ {
+ storageKey = !string.IsNullOrEmpty(keys.PrimaryKey) ? keys.PrimaryKey : keys.SecondaryKey;
+ }
+ }
+ }
+
+ return storageKey;
+ }
+
+ protected override void ProcessRecord()
+ {
+ base.ProcessRecord();
+ ExecuteCommand();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/VirtualMachineDiagnosticsExtensionCmdletBase.cs b/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/VirtualMachineDiagnosticsExtensionCmdletBase.cs
new file mode 100644
index 000000000000..e730fd6f3634
--- /dev/null
+++ b/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/VirtualMachineDiagnosticsExtensionCmdletBase.cs
@@ -0,0 +1,32 @@
+// ----------------------------------------------------------------------------------
+//
+// Copyright Microsoft Corporation
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ----------------------------------------------------------------------------------
+
+namespace Microsoft.Azure.Commands.Compute
+{
+ public class VirtualMachineDiagnosticsExtensionCmdletBase : VirtualMachineExtensionBaseCmdlet
+ {
+ protected const string DiagnosticsExtensionNamespace = "Microsoft.Azure.Diagnostics";
+ protected const string DiagnosticsExtensionType = "IaaSDiagnostics";
+
+ protected string StorageAccountName { get; set; }
+ protected string StorageKey { get; set; }
+ protected string Endpoint { get; set; }
+
+ public VirtualMachineDiagnosticsExtensionCmdletBase()
+ : base()
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ServiceManagement/Compute/Commands.ServiceManagement/IaaS/Extensions/Diagnostics/SetAzureVMDiagnosticsExtension.cs b/src/ServiceManagement/Compute/Commands.ServiceManagement/IaaS/Extensions/Diagnostics/SetAzureVMDiagnosticsExtension.cs
index 1d4ffeaa82e0..3d9854dfda4b 100644
--- a/src/ServiceManagement/Compute/Commands.ServiceManagement/IaaS/Extensions/Diagnostics/SetAzureVMDiagnosticsExtension.cs
+++ b/src/ServiceManagement/Compute/Commands.ServiceManagement/IaaS/Extensions/Diagnostics/SetAzureVMDiagnosticsExtension.cs
@@ -21,7 +21,9 @@
using Microsoft.WindowsAzure.Commands.Common.Storage;
using Microsoft.WindowsAzure.Commands.ServiceManagement.Model;
using Microsoft.WindowsAzure.Commands.ServiceManagement.Properties;
+using Microsoft.WindowsAzure.Commands.Utilities.Common;
using Microsoft.WindowsAzure.Management.Storage;
+using Newtonsoft.Json;
namespace Microsoft.WindowsAzure.Commands.ServiceManagement.IaaS.Extensions
{
@@ -33,11 +35,11 @@ namespace Microsoft.WindowsAzure.Commands.ServiceManagement.IaaS.Extensions
typeof(IPersistentVM))]
public class SetAzureVMDiagnosticsExtensionCommand : VirtualMachineDiagnosticsExtensionCmdletBase
{
+ private string publicConfiguration;
+ private string privateConfiguration;
+ private string storageKey;
protected const string SetExtParamSetName = "SetDiagnosticsExtension";
protected const string SetExtRefParamSetName = "SetDiagnosticsWithReferenceExtension";
- private const string PublicConfigurationTemplate = "\"xmlCfg\":\"{0}\", \"StorageAccount\":\"{1}\" ";
- private readonly string PrivateConfigurationTemplate = "\"storageAccountName\":\"{0}\", \"storageAccountKey\":\"{1}\", \"storageAccountEndPoint\":\"{2}\"";
- private readonly string XmlNamespace = "http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration";
[Parameter(
ParameterSetName = SetExtParamSetName,
Mandatory = true,
@@ -106,117 +108,91 @@ public AzureStorageContext StorageContext
HelpMessage = "To specify the reference name.")]
public override string ReferenceName { get; set; }
- internal void ExecuteCommand()
+ public string StorageAccountName
{
- ValidateParameters();
- RemovePredicateExtensions();
- AddResourceExtension();
- WriteObject(VM);
- UpdateAzureVMCommand cmd = new UpdateAzureVMCommand();
- }
-
- protected override void ValidateParameters()
- {
- base.ValidateParameters();
- ValidateStorageAccount();
- ValidateConfiguration();
- ExtensionName = DiagnosticsExtensionType;
- Publisher = DiagnosticsExtensionNamespace;
-
- // If the user didn't specify an extension reference name and the input VM already has a diagnostics extension,
- // reuse its reference name
- if (string.IsNullOrEmpty(ReferenceName))
+ get
{
- ResourceExtensionReference diagnosticsExtension = ResourceExtensionReferences.FirstOrDefault(ExtensionPredicate);
- if (diagnosticsExtension != null)
- {
- ReferenceName = diagnosticsExtension.ReferenceName;
- }
+ return this.StorageContext.StorageAccountName;
}
}
- private void ValidateStorageAccount()
+ public string Endpoint
{
- StorageAccountName = StorageContext.StorageAccountName;
- StorageKey = GetStorageKey();
- // We need the suffix, NOT the full account endpoint.
- Endpoint = "https://" + StorageContext.EndPointSuffix;
+ get
+ {
+ return "https://" + this.StorageContext.EndPointSuffix;
+ }
}
- private void ValidateConfiguration()
+ public string StorageKey
{
- // Public configuration must look like:
- // { "xmlCfg":"base-64 encoded string", "StorageAccount":"account_name", "localResourceDirectory":{ "path":"some_path", "expandResourceDirectory": }}
- //
- // localResourceDirectory is optional
- //
- // What we have in is something like:
- //
- //
- //
- //
- // ...
- //
- // element and extract it
- string fullConfig = sr.ReadToEnd();
- int wadCfgBeginIndex = fullConfig.IndexOf("");
- if (wadCfgBeginIndex == -1)
+ if (string.IsNullOrEmpty(this.storageKey))
{
- throw new ArgumentException(Resources.IaasDiagnosticsBadConfigNoWadCfg);
+ this.storageKey = GetStorageKey();
}
- int wadCfgEndIndex = fullConfig.IndexOf("");
- if(wadCfgEndIndex == -1)
- {
- throw new ArgumentException(Resources.IaasDiagnosticsBadConfigNoEndWadCfg);
- }
+ return this.storageKey;
+ }
+ }
- if(wadCfgEndIndex <= wadCfgBeginIndex)
+ public override string PublicConfiguration
+ {
+ get
+ {
+ if (string.IsNullOrEmpty(this.publicConfiguration))
{
- throw new ArgumentException(Resources.IaasDiagnosticsBadConfigNoMatchingWadCfg);
+ this.publicConfiguration =
+ JsonConvert.SerializeObject(DiagnosticsHelper.GetPublicDiagnosticsConfigurationFromFile(this.DiagnosticsConfigurationPath,
+ this.StorageAccountName));
}
- config = fullConfig.Substring(wadCfgBeginIndex, wadCfgEndIndex + "".Length - wadCfgBeginIndex);
- config = Convert.ToBase64String(Encoding.UTF8.GetBytes(config.ToCharArray()));
+ return this.publicConfiguration;
}
+ }
- // Now extract the local resource directory element
- XmlDocument doc = new XmlDocument();
- XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
- ns.AddNamespace("ns", XmlNamespace);
- doc.Load(DiagnosticsConfigurationPath);
- var node = doc.SelectSingleNode("//ns:LocalResourceDirectory", ns);
- string localDirectory = (node != null && node.Attributes != null) ? node.Attributes["path"].Value : null;
- string localDirectoryExpand = (node != null && node.Attributes != null) ? node.Attributes["expandEnvironment"].Value : null;
- if (localDirectoryExpand == "0")
- {
- localDirectoryExpand = "false";
- }
- if (localDirectoryExpand == "1")
+ public override string PrivateConfiguration
+ {
+ get
{
- localDirectoryExpand = "true";
+ if (string.IsNullOrEmpty(this.privateConfiguration))
+ {
+ this.privateConfiguration =
+ JsonConvert.SerializeObject(DiagnosticsHelper.GetPrivateDiagnosticsConfiguration(this.StorageAccountName, this.StorageKey,
+ this.Endpoint));
+ }
+
+ return this.privateConfiguration;
}
+ }
- PublicConfiguration = "{ ";
- PublicConfiguration += string.Format(PublicConfigurationTemplate, config, StorageAccountName);
- if (!string.IsNullOrEmpty(localDirectory))
- {
- PublicConfiguration += ", \"localResourceDirectory\":{ \"path\":\"" + localDirectory + "\", \"expandResourceDirectory\":" + localDirectoryExpand + "}";
- }
+ internal void ExecuteCommand()
+ {
+ ValidateParameters();
+ RemovePredicateExtensions();
+ AddResourceExtension();
+ WriteObject(VM);
+ UpdateAzureVMCommand cmd = new UpdateAzureVMCommand();
+ }
- PublicConfiguration += "}";
+ protected override void ValidateParameters()
+ {
+ base.ValidateParameters();
+ ExtensionName = DiagnosticsExtensionType;
+ Publisher = DiagnosticsExtensionNamespace;
- // Private configuration must look like:
- // { "storageAccountName":"your_account_name", "storageAccountKey":"your_key", "storageAccountEndPoint":"end_point" }
- PrivateConfiguration = "{ ";
- PrivateConfiguration += string.Format(PrivateConfigurationTemplate, StorageAccountName, StorageKey, Endpoint);
- PrivateConfiguration += "}";
+ // If the user didn't specify an extension reference name and the input VM already has a diagnostics extension,
+ // reuse its reference name
+ if (string.IsNullOrEmpty(ReferenceName))
+ {
+ ResourceExtensionReference diagnosticsExtension = ResourceExtensionReferences.FirstOrDefault(ExtensionPredicate);
+ if (diagnosticsExtension != null)
+ {
+ ReferenceName = diagnosticsExtension.ReferenceName;
+ }
+ }
}
protected string GetStorageKey()
diff --git a/src/ServiceManagement/Compute/Commands.ServiceManagement/IaaS/Extensions/Diagnostics/VirtualMachineDiagnosticsExtensionCmdletBase.cs b/src/ServiceManagement/Compute/Commands.ServiceManagement/IaaS/Extensions/Diagnostics/VirtualMachineDiagnosticsExtensionCmdletBase.cs
index d8e0b599439d..94d7e7407a5f 100644
--- a/src/ServiceManagement/Compute/Commands.ServiceManagement/IaaS/Extensions/Diagnostics/VirtualMachineDiagnosticsExtensionCmdletBase.cs
+++ b/src/ServiceManagement/Compute/Commands.ServiceManagement/IaaS/Extensions/Diagnostics/VirtualMachineDiagnosticsExtensionCmdletBase.cs
@@ -20,10 +20,6 @@ public class VirtualMachineDiagnosticsExtensionCmdletBase : VirtualMachineExtens
protected const string DiagnosticsExtensionType = "IaaSDiagnostics";
protected const string VirtualMachineDiagnosticsExtensionNoun = "AzureVMDiagnosticsExtension";
- protected string StorageAccountName { get; set; }
- protected string StorageKey { get; set; }
- protected string Endpoint { get; set; }
-
public VirtualMachineDiagnosticsExtensionCmdletBase()
: base()
{