diff --git a/src/ResourceManager/Compute/Commands.Compute/Common/DiagnosticsHelper.cs b/src/ResourceManager/Compute/Commands.Compute/Common/DiagnosticsHelper.cs index 0bddae72680d..9598fe3ec0ee 100644 --- a/src/ResourceManager/Compute/Commands.Compute/Common/DiagnosticsHelper.cs +++ b/src/ResourceManager/Compute/Commands.Compute/Common/DiagnosticsHelper.cs @@ -14,6 +14,7 @@ using System; using System.Collections; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Management.Automation; @@ -34,7 +35,6 @@ namespace Microsoft.Azure.Commands.Compute.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 WadCfg = "WadCfg"; private static string WadCfgBlob = "WadCfgBlob"; @@ -46,6 +46,7 @@ public static class DiagnosticsHelper private static string StorageAccountKeyTag = "storageAccountKey"; private static string StorageAccountEndPointTag = "storageAccountEndPoint"; + public static string XmlNamespace = "http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration"; public static string DiagnosticsConfigurationElemStr = "DiagnosticsConfiguration"; public static string DiagnosticMonitorConfigurationElemStr = "DiagnosticMonitorConfiguration"; public static string PublicConfigElemStr = "PublicConfig"; @@ -56,6 +57,10 @@ public static class DiagnosticsHelper public static string PrivConfEndpointAttr = "endpoint"; public static string MetricsElemStr = "Metrics"; public static string MetricsResourceIdAttr = "resourceId"; + public static string EventHubElemStr = "EventHub"; + public static string EventHubUrlAttr = "Url"; + public static string EventHubSharedAccessKeyNameAttr = "SharedAccessKeyName"; + public static string EventHubSharedAccessKeyAttr = "SharedAccessKey"; public enum ConfigFileType { @@ -246,17 +251,36 @@ private static void AutoFillMetricsConfig(JObject wadCfgObject, string resourceI } } - public static Hashtable GetPrivateDiagnosticsConfiguration(string storageAccountName, - string storageKey, string endpoint) + public static Hashtable GetPrivateDiagnosticsConfiguration(string configurationPath, + string storageAccountName, string storageKey, string endpoint) { var privateConfig = new Hashtable(); privateConfig.Add(StorageAccountNameTag, storageAccountName); privateConfig.Add(StorageAccountKeyTag, storageKey); privateConfig.Add(StorageAccountEndPointTag, endpoint); + AddEventHubPrivateConfig(privateConfig, configurationPath); + return privateConfig; } + private static void AddEventHubPrivateConfig(Hashtable privateConfig, string configurationPath) + { + var eventHubUrl = GetConfigValueFromPrivateConfig(configurationPath, EventHubElemStr, EventHubUrlAttr); + var eventHubSharedAccessKeyName = GetConfigValueFromPrivateConfig(configurationPath, EventHubElemStr, EventHubSharedAccessKeyNameAttr); + var eventHubSharedAccessKey = GetConfigValueFromPrivateConfig(configurationPath, EventHubElemStr, EventHubSharedAccessKeyAttr); + + if (!string.IsNullOrEmpty(eventHubUrl) || !string.IsNullOrEmpty(eventHubSharedAccessKeyName) || !string.IsNullOrEmpty(eventHubSharedAccessKey)) + { + var eventHubConfig = new Hashtable(); + eventHubConfig.Add(EventHubUrlAttr, eventHubUrl); + eventHubConfig.Add(EventHubSharedAccessKeyNameAttr, eventHubSharedAccessKeyName); + eventHubConfig.Add(EventHubSharedAccessKeyAttr, eventHubSharedAccessKey); + + privateConfig.Add(EventHubElemStr, eventHubConfig); + } + } + private static XElement GetPublicConfigXElementFromXmlFile(string configurationPath) { XElement publicConfig = null; @@ -292,9 +316,34 @@ private static JObject GetPublicConfigJObjectFromJsonFile(string configurationPa return publicConfig; } - public static string GetStorageAccountInfoFromPrivateConfig(string configurationPath, string attributeName) + /// + /// Get the private config value for a specific attribute. + /// The private config looks like this: + /// XML: + /// + /// + /// + /// + /// + /// JSON: + /// "PrivateConfig":{ + /// "storageAccountName":"name", + /// "storageAccountKey":"key", + /// "storageAccountEndPoint":"endpoint", + /// "EventHub":{ + /// "Url":"url", + /// "SharedAccessKeyName":"sasKeyName", + /// "SharedAccessKey":"sasKey" + /// } + /// } + /// + /// The path to the configuration file + /// The element name of the private config. e.g., StorageAccount, EventHub + /// The attribute name of the element + /// + public static string GetConfigValueFromPrivateConfig(string configurationPath, string elementName, string attributeName) { - string value = null; + string value = string.Empty; var configFileType = GetConfigFileType(configurationPath); if (configFileType == ConfigFileType.Xml) @@ -304,25 +353,54 @@ public static string GetStorageAccountInfoFromPrivateConfig(string configuration if (xmlConfig.Name.LocalName == DiagnosticsConfigurationElemStr) { var privateConfigElem = xmlConfig.Elements().FirstOrDefault(ele => ele.Name.LocalName == PrivateConfigElemStr); - var storageAccountElem = privateConfigElem == null ? null : privateConfigElem.Elements().FirstOrDefault(ele => ele.Name.LocalName == StorageAccountElemStr); - var attribute = storageAccountElem == null ? null : storageAccountElem.Attributes().FirstOrDefault(a => string.Equals(a.Name.LocalName, attributeName)); + var configElem = privateConfigElem == null ? null : privateConfigElem.Elements().FirstOrDefault(ele => ele.Name.LocalName == elementName); + var attribute = configElem == null ? null : configElem.Attributes().FirstOrDefault(a => string.Equals(a.Name.LocalName, attributeName)); value = attribute == null ? null : attribute.Value; } } else if (configFileType == ConfigFileType.Json) { + // Find the PrivateConfig var jsonConfig = JsonConvert.DeserializeObject(File.ReadAllText(configurationPath)); var properties = jsonConfig.Properties().Select(p => p.Name); + var privateConfigProperty = properties.FirstOrDefault(p => p.Equals(PrivateConfigElemStr)); - var privateConfigProperty = properties.FirstOrDefault(p => p.Equals(PrivateConfigElemStr, StringComparison.OrdinalIgnoreCase)); - if (privateConfigProperty != null) + if (privateConfigProperty == null) + { + return value; + } + var privateConfig = jsonConfig[privateConfigProperty] as JObject; + + // Find the target config object corresponding to elementName + JObject targetConfig = null; + if (elementName == StorageAccountElemStr) + { + // Special handling as private storage config is flattened + targetConfig = privateConfig; + var attributeNameMapping = new Dictionary() + { + { PrivConfNameAttr, "storageAccountName" }, + { PrivConfKeyAttr, "storageAccountKey" }, + { PrivConfEndpointAttr, "storageAccountEndPoint" } + }; + attributeName = attributeNameMapping.FirstOrDefault(m => m.Key == attributeName).Value; + } + else { - var privateConfig = jsonConfig[privateConfigProperty] as JObject; properties = privateConfig.Properties().Select(p => p.Name); + var configProperty = properties.FirstOrDefault(p => p.Equals(elementName)); + targetConfig = configProperty == null ? null : privateConfig[configProperty] as JObject; + } - var attributeProperty = properties.FirstOrDefault(p => p.Equals(attributeName, StringComparison.OrdinalIgnoreCase)); - value = attributeProperty == null ? null : privateConfig[attributeProperty].Value(); + if (targetConfig == null || attributeName == null) + { + return value; } + + // Find the config value corresponding to attributeName + properties = targetConfig.Properties().Select(p => p.Name); + var attributeProperty = properties.FirstOrDefault(p => p.Equals(attributeName)); + value = attributeProperty == null ? null : targetConfig[attributeProperty].Value(); } return value; @@ -381,7 +459,7 @@ public static string InitializeStorageAccountKey(IStorageManagementClient storag else { // Use the one defined in PrivateConfig - storageAccountKey = GetStorageAccountInfoFromPrivateConfig(configurationPath, PrivConfKeyAttr); + storageAccountKey = GetConfigValueFromPrivateConfig(configurationPath, StorageAccountElemStr, PrivConfKeyAttr); } return storageAccountKey; @@ -414,7 +492,7 @@ public static string InitializeStorageAccountEndpoint(string storageAccountName, storageAccountEndpoint = GetEndpointFromStorageContext(context); } else if (!string.IsNullOrEmpty( - storageAccountEndpoint = GetStorageAccountInfoFromPrivateConfig(configurationPath, PrivConfEndpointAttr))) + storageAccountEndpoint = GetConfigValueFromPrivateConfig(configurationPath, StorageAccountElemStr, PrivConfEndpointAttr))) { // We can get the value from PrivateConfig } diff --git a/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/SetAzureRmVMDiagnosticsExtension.cs b/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/SetAzureRmVMDiagnosticsExtension.cs index 075356f34e55..6354ca3dbcf2 100644 --- a/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/SetAzureRmVMDiagnosticsExtension.cs +++ b/src/ResourceManager/Compute/Commands.Compute/Extension/Diagnostics/SetAzureRmVMDiagnosticsExtension.cs @@ -194,9 +194,8 @@ private Hashtable PrivateConfiguration { if (this.privateConfiguration == null) { - this.privateConfiguration = DiagnosticsHelper.GetPrivateDiagnosticsConfiguration(this.StorageAccountName, - this.StorageAccountKey, - this.StorageAccountEndpoint); + this.privateConfiguration = DiagnosticsHelper.GetPrivateDiagnosticsConfiguration(this.DiagnosticsConfigurationPath, + this.StorageAccountName, this.StorageAccountKey, this.StorageAccountEndpoint); } return this.privateConfiguration; diff --git a/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/Commands.ServiceManagement.Test.csproj b/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/Commands.ServiceManagement.Test.csproj index 1a0d14a851d3..1ab3a446f723 100644 --- a/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/Commands.ServiceManagement.Test.csproj +++ b/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/Commands.ServiceManagement.Test.csproj @@ -457,6 +457,7 @@ True Resource.resx + @@ -577,6 +578,12 @@ Always + + Always + + + Always + diff --git a/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/FunctionalTests/Constants.cs b/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/FunctionalTests/Constants.cs index 70ea7c2f2b06..c27549eb80d1 100644 --- a/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/FunctionalTests/Constants.cs +++ b/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/FunctionalTests/Constants.cs @@ -17,13 +17,17 @@ namespace Microsoft.WindowsAzure.Commands.ServiceManagement.Test public class Category { public const string Scenario = "AzureRTScenario"; - public const string BVT = "BVT"; public const string Functional = "Functional"; public const string Preview = "Preview"; public const string Sequential = "Sequential"; public const string Network = "Network"; public const string Upload = "AzureRTUpload"; public const string CleanUp = "AzureRTCleanUp"; + + // Acceptance type + public const string AcceptanceType = "AcceptanceType"; + public const string BVT = "BVT"; + public const string CheckIn = "CheckIn"; } public class LoadBalancerDistribution diff --git a/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/Resources/Diagnostics/config.json b/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/Resources/Diagnostics/config.json new file mode 100644 index 000000000000..c8e03b752b3d --- /dev/null +++ b/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/Resources/Diagnostics/config.json @@ -0,0 +1,134 @@ +{ + "PublicConfig": { + "WadCfg": { + "DiagnosticMonitorConfiguration": { + "DiagnosticInfrastructureLogs": { + "scheduledTransferLogLevelFilter": "Error" + }, + "Directories": { + "IISLogs": { + "containerName": "wad-iis-logfiles" + }, + "FailedRequestLogs": { + "containerName": "wad-failedrequestlogs" + }, + "scheduledTransferPeriod": "PT1M" + }, + "PerformanceCounters": { + "PerformanceCounterConfiguration": [ + { + "annotation": [ + + ], + "counterSpecifier": "\\Memory\\Available MBytes", + "sampleRate": "PT15S", + "sinks": "HotPath" + }, + { + "annotation": [ + + ], + "counterSpecifier": "\\Web Service(_Total)\\ISAPI Extension Requests/sec", + "sampleRate": "PT3M" + }, + { + "annotation": [ + + ], + "counterSpecifier": "\\Web Service(_Total)\\Bytes Total/Sec", + "sampleRate": "PT3M" + }, + { + "annotation": [ + + ], + "counterSpecifier": "\\ASP.NET Applications(__Total__)\\Requests/Sec", + "sampleRate": "PT3M" + }, + { + "annotation": [ + + ], + "counterSpecifier": "\\ASP.NET Applications(__Total__)\\Errors Total/Sec", + "sampleRate": "PT3M" + }, + { + "annotation": [ + + ], + "counterSpecifier": "\\ASP.NET\\Requests Queued", + "sampleRate": "PT3M" + }, + { + "annotation": [ + + ], + "counterSpecifier": "\\ASP.NET\\Requests Rejected", + "sampleRate": "PT3M" + }, + { + "annotation": [ + + ], + "counterSpecifier": "\\Processor(_Total)\\% Processor Time", + "sampleRate": "PT3M" + } + ], + "scheduledTransferPeriod": "PT1M" + }, + "WindowsEventLog": { + "sinks": "HotPath", + "DataSource": [ + { + "name": "Application!*[System[(Level=1 or Level=2 or Level=3)]]" + }, + { + "name": "Windows Azure!*[System[(Level=1 or Level=2 or Level=3 or Level=4)]]" + } + ], + "scheduledTransferPeriod": "PT1M" + }, + "CrashDumps": { + "CrashDumpConfiguration": [ + { + "processName": "WaIISHost.exe" + }, + { + "processName": "WaWorkerHost.exe" + }, + { + "processName": "w3wp.exe" + } + ] + }, + "Logs": { + "scheduledTransferLogLevelFilter": "Error", + "scheduledTransferPeriod": "PT1M" + }, + "overallQuotaInMB": 4096 + }, + "SinksConfig": { + "Sink": [ + { + "name": "HotPath", + "EventHub": { + "Url": "Url", + "SharedAccessKeyName": "sasKeyName" + } + } + ] + } + }, + "StorageAccount": "yanmingv2vm9503" + }, + "PrivateConfig": { + "storageAccountName": "storageAccountName", + "storageAccountKey": "storageAccountKey", + "storageAccountEndPoint": "https://core.windows.net/", + "EventHub": { + "Url": "Url", + "SharedAccessKeyName": "sasKeyName", + "SharedAccessKey": "sasKey" + } + } +} \ No newline at end of file diff --git a/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/Resources/Diagnostics/diagnostics.wadcfgx b/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/Resources/Diagnostics/diagnostics.wadcfgx new file mode 100644 index 000000000000..7240bc4011cd --- /dev/null +++ b/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/Resources/Diagnostics/diagnostics.wadcfgx @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + \ No newline at end of file diff --git a/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/UnitTests/Cmdlets/IaaS/Extensions/Diagnostics/DiagnosticsHelperTest.cs b/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/UnitTests/Cmdlets/IaaS/Extensions/Diagnostics/DiagnosticsHelperTest.cs new file mode 100644 index 000000000000..1b0daa8abc0f --- /dev/null +++ b/src/ServiceManagement/Compute/Commands.ServiceManagement.Test/UnitTests/Cmdlets/IaaS/Extensions/Diagnostics/DiagnosticsHelperTest.cs @@ -0,0 +1,37 @@ +using System.Collections; +using Microsoft.WindowsAzure.Commands.ServiceManagement.Common; +using Xunit; + +namespace Microsoft.WindowsAzure.Commands.ServiceManagement.Test.UnitTests.Cmdlets.IaaS.Extensions.Diagnostics +{ + public class DiagnosticsHelperTest + { + [Fact] + [Trait(Category.AcceptanceType, Category.CheckIn)] + public void TestGetEventHubFromJsonConfig() + { + var table = new Hashtable(); + DiagnosticsHelper.AddEventHubPrivateConfig(table, @"Resources\Diagnostics\config.json"); + + var eventHubConfig = table["EventHub"] as Hashtable; + Assert.NotNull(eventHubConfig); + Assert.Equal(eventHubConfig["Url"], "Url"); + Assert.Equal(eventHubConfig["SharedAccessKeyName"], "sasKeyName"); + Assert.Equal(eventHubConfig["SharedAccessKey"], "sasKey"); + } + + [Fact] + [Trait(Category.AcceptanceType, Category.CheckIn)] + public void TestGetEventHubFromXmlConfig() + { + var table = new Hashtable(); + DiagnosticsHelper.AddEventHubPrivateConfig(table, @"Resources\Diagnostics\diagnostics.wadcfgx"); + + var eventHubConfig = table["EventHub"] as Hashtable; + Assert.NotNull(eventHubConfig); + Assert.Equal(eventHubConfig["Url"], "Url"); + Assert.Equal(eventHubConfig["SharedAccessKeyName"], "sasKeyName"); + Assert.Equal(eventHubConfig["SharedAccessKey"], "sasKey"); + } + } +} diff --git a/src/ServiceManagement/Compute/Commands.ServiceManagement/Common/DiagnosticsHelper.cs b/src/ServiceManagement/Compute/Commands.ServiceManagement/Common/DiagnosticsHelper.cs index 5d3a41fa2560..ca3ff3be1767 100644 --- a/src/ServiceManagement/Compute/Commands.ServiceManagement/Common/DiagnosticsHelper.cs +++ b/src/ServiceManagement/Compute/Commands.ServiceManagement/Common/DiagnosticsHelper.cs @@ -14,6 +14,7 @@ using System; using System.Collections; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Management.Automation; @@ -33,7 +34,6 @@ namespace Microsoft.WindowsAzure.Commands.ServiceManagement.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 WadCfg = "WadCfg"; private static string WadCfgBlob = "WadCfgBlob"; @@ -45,6 +45,7 @@ public static class DiagnosticsHelper private static string StorageAccountKeyTag = "storageAccountKey"; private static string StorageAccountEndPointTag = "storageAccountEndPoint"; + public static string XmlNamespace = "http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration"; public static string DiagnosticsConfigurationElemStr = "DiagnosticsConfiguration"; public static string DiagnosticMonitorConfigurationElemStr = "DiagnosticMonitorConfiguration"; public static string PublicConfigElemStr = "PublicConfig"; @@ -55,6 +56,10 @@ public static class DiagnosticsHelper public static string PrivConfEndpointAttr = "endpoint"; public static string MetricsElemStr = "Metrics"; public static string MetricsResourceIdAttr = "resourceId"; + public static string EventHubElemStr = "EventHub"; + public static string EventHubUrlAttr = "Url"; + public static string EventHubSharedAccessKeyNameAttr = "SharedAccessKeyName"; + public static string EventHubSharedAccessKeyAttr = "SharedAccessKey"; public enum ConfigFileType { @@ -245,17 +250,36 @@ private static void AutoFillMetricsConfig(JObject wadCfgObject, string resourceI } } - public static Hashtable GetPrivateDiagnosticsConfiguration(string storageAccountName, - string storageKey, string endpoint) + public static Hashtable GetPrivateDiagnosticsConfiguration(string configurationPath, + string storageAccountName, string storageKey, string endpoint) { var privateConfig = new Hashtable(); privateConfig.Add(StorageAccountNameTag, storageAccountName); privateConfig.Add(StorageAccountKeyTag, storageKey); privateConfig.Add(StorageAccountEndPointTag, endpoint); + AddEventHubPrivateConfig(privateConfig, configurationPath); + return privateConfig; } + internal static void AddEventHubPrivateConfig(Hashtable privateConfig, string configurationPath) + { + var eventHubUrl = GetConfigValueFromPrivateConfig(configurationPath, EventHubElemStr, EventHubUrlAttr); + var eventHubSharedAccessKeyName = GetConfigValueFromPrivateConfig(configurationPath, EventHubElemStr, EventHubSharedAccessKeyNameAttr); + var eventHubSharedAccessKey = GetConfigValueFromPrivateConfig(configurationPath, EventHubElemStr, EventHubSharedAccessKeyAttr); + + if (!string.IsNullOrEmpty(eventHubUrl) || !string.IsNullOrEmpty(eventHubSharedAccessKeyName) || !string.IsNullOrEmpty(eventHubSharedAccessKey)) + { + var eventHubConfig = new Hashtable(); + eventHubConfig.Add(EventHubUrlAttr, eventHubUrl); + eventHubConfig.Add(EventHubSharedAccessKeyNameAttr, eventHubSharedAccessKeyName); + eventHubConfig.Add(EventHubSharedAccessKeyAttr, eventHubSharedAccessKey); + + privateConfig.Add(EventHubElemStr, eventHubConfig); + } + } + private static XElement GetPublicConfigXElementFromXmlFile(string configurationPath) { XElement publicConfig = null; @@ -291,9 +315,34 @@ private static JObject GetPublicConfigJObjectFromJsonFile(string configurationPa return publicConfig; } - public static string GetStorageAccountInfoFromPrivateConfig(string configurationPath, string attributeName) + /// + /// Get the private config value for a specific attribute. + /// The private config looks like this: + /// XML: + /// + /// + /// + /// + /// + /// JSON: + /// "PrivateConfig":{ + /// "storageAccountName":"name", + /// "storageAccountKey":"key", + /// "storageAccountEndPoint":"endpoint", + /// "EventHub":{ + /// "Url":"url", + /// "SharedAccessKeyName":"sasKeyName", + /// "SharedAccessKey":"sasKey" + /// } + /// } + /// + /// The path to the configuration file + /// The element name of the private config. e.g., StorageAccount, EventHub + /// The attribute name of the element + /// + public static string GetConfigValueFromPrivateConfig(string configurationPath, string elementName, string attributeName) { - string value = null; + string value = string.Empty; var configFileType = GetConfigFileType(configurationPath); if (configFileType == ConfigFileType.Xml) @@ -303,25 +352,54 @@ public static string GetStorageAccountInfoFromPrivateConfig(string configuration if (xmlConfig.Name.LocalName == DiagnosticsConfigurationElemStr) { var privateConfigElem = xmlConfig.Elements().FirstOrDefault(ele => ele.Name.LocalName == PrivateConfigElemStr); - var storageAccountElem = privateConfigElem == null ? null : privateConfigElem.Elements().FirstOrDefault(ele => ele.Name.LocalName == StorageAccountElemStr); - var attribute = storageAccountElem == null ? null : storageAccountElem.Attributes().FirstOrDefault(a => string.Equals(a.Name.LocalName, attributeName)); + var configElem = privateConfigElem == null ? null : privateConfigElem.Elements().FirstOrDefault(ele => ele.Name.LocalName == elementName); + var attribute = configElem == null ? null : configElem.Attributes().FirstOrDefault(a => string.Equals(a.Name.LocalName, attributeName)); value = attribute == null ? null : attribute.Value; } } else if (configFileType == ConfigFileType.Json) { + // Find the PrivateConfig var jsonConfig = JsonConvert.DeserializeObject(File.ReadAllText(configurationPath)); var properties = jsonConfig.Properties().Select(p => p.Name); + var privateConfigProperty = properties.FirstOrDefault(p => p.Equals(PrivateConfigElemStr)); - var privateConfigProperty = properties.FirstOrDefault(p => p.Equals(PrivateConfigElemStr, StringComparison.OrdinalIgnoreCase)); - if (privateConfigProperty != null) + if (privateConfigProperty == null) + { + return value; + } + var privateConfig = jsonConfig[privateConfigProperty] as JObject; + + // Find the target config object corresponding to elementName + JObject targetConfig = null; + if (elementName == StorageAccountElemStr) + { + // Special handling as private storage config is flattened + targetConfig = privateConfig; + var attributeNameMapping = new Dictionary() + { + { PrivConfNameAttr, "storageAccountName" }, + { PrivConfKeyAttr, "storageAccountKey" }, + { PrivConfEndpointAttr, "storageAccountEndPoint" } + }; + attributeName = attributeNameMapping.FirstOrDefault(m => m.Key == attributeName).Value; + } + else { - var privateConfig = jsonConfig[privateConfigProperty] as JObject; properties = privateConfig.Properties().Select(p => p.Name); + var configProperty = properties.FirstOrDefault(p => p.Equals(elementName)); + targetConfig = configProperty == null ? null : privateConfig[configProperty] as JObject; + } - var attributeProperty = properties.FirstOrDefault(p => p.Equals(attributeName, StringComparison.OrdinalIgnoreCase)); - value = attributeProperty == null ? null : privateConfig[attributeProperty].Value(); + if (targetConfig == null || attributeName == null) + { + return value; } + + // Find the config value corresponding to attributeName + properties = targetConfig.Properties().Select(p => p.Name); + var attributeProperty = properties.FirstOrDefault(p => p.Equals(attributeName)); + value = attributeProperty == null ? null : targetConfig[attributeProperty].Value(); } return value; @@ -382,7 +460,7 @@ public static string InitializeStorageAccountKey(IStorageManagementClient storag else { // Use the one defined in PrivateConfig - storageAccountKey = GetStorageAccountInfoFromPrivateConfig(configurationPath, PrivConfKeyAttr); + storageAccountKey = GetConfigValueFromPrivateConfig(configurationPath, StorageAccountElemStr, PrivConfKeyAttr); } return storageAccountKey; @@ -416,7 +494,7 @@ public static string InitializeStorageAccountEndpoint(string storageAccountName, storageAccountEndpoint = GetEndpointFromStorageContext(context); } else if (!string.IsNullOrEmpty( - storageAccountEndpoint = GetStorageAccountInfoFromPrivateConfig(configurationPath, PrivConfEndpointAttr))) + storageAccountEndpoint = GetConfigValueFromPrivateConfig(configurationPath, StorageAccountElemStr, PrivConfEndpointAttr))) { // We can get value from PrivateConfig } diff --git a/src/ServiceManagement/Compute/Commands.ServiceManagement/Extensions/Diagnostics/BaseAzureServiceDiagnosticsExtension.cs b/src/ServiceManagement/Compute/Commands.ServiceManagement/Extensions/Diagnostics/BaseAzureServiceDiagnosticsExtension.cs index 18cc0e98065a..dd1ab22b014a 100644 --- a/src/ServiceManagement/Compute/Commands.ServiceManagement/Extensions/Diagnostics/BaseAzureServiceDiagnosticsExtension.cs +++ b/src/ServiceManagement/Compute/Commands.ServiceManagement/Extensions/Diagnostics/BaseAzureServiceDiagnosticsExtension.cs @@ -49,7 +49,7 @@ protected override void ValidateParameters() { base.ValidateParameters(); - XNamespace configNameSpace = "http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration"; + XNamespace configNameSpace = DiagnosticsHelper.XmlNamespace; ProviderNamespace = DiagnosticsExtensionNamespace; ExtensionName = DiagnosticsExtensionType; @@ -158,7 +158,7 @@ protected override void ValidateConfiguration() PublicConfiguration = publicConfigElement.ToString(); // Make sure the storage account name in PrivateConfig matches. - var privateConfigStorageAccountName = DiagnosticsHelper.GetStorageAccountInfoFromPrivateConfig(this.DiagnosticsConfigurationPath, DiagnosticsHelper.PrivConfNameAttr); + var privateConfigStorageAccountName = DiagnosticsHelper.GetConfigValueFromPrivateConfig(this.DiagnosticsConfigurationPath, DiagnosticsHelper.StorageAccountElemStr, DiagnosticsHelper.PrivConfNameAttr); if (!string.IsNullOrEmpty(privateConfigStorageAccountName) && !string.Equals(StorageAccountName, privateConfigStorageAccountName, StringComparison.OrdinalIgnoreCase)) { @@ -169,6 +169,8 @@ protected override void ValidateConfiguration() SetPrivateConfigAttribute(DiagnosticsHelper.StorageAccountElemStr, DiagnosticsHelper.PrivConfNameAttr, StorageAccountName); SetPrivateConfigAttribute(DiagnosticsHelper.StorageAccountElemStr, DiagnosticsHelper.PrivConfKeyAttr, StorageAccountKey); SetPrivateConfigAttribute(DiagnosticsHelper.StorageAccountElemStr, DiagnosticsHelper.PrivConfEndpointAttr, StorageAccountEndpoint); + AddEventHubPrivateConfig(PrivateConfigurationXml); + PrivateConfiguration = PrivateConfigurationXml.ToString(); } @@ -192,5 +194,23 @@ private string GetResourceId() Profile.DefaultSubscription.Id, resourceGroup, ServiceName) : null; } + + private void AddEventHubPrivateConfig(XDocument privateConfig) + { + var eventHubUrl = DiagnosticsHelper.GetConfigValueFromPrivateConfig(this.DiagnosticsConfigurationPath, DiagnosticsHelper.EventHubElemStr, DiagnosticsHelper.EventHubUrlAttr); + var eventHubSharedAccessKeyName = DiagnosticsHelper.GetConfigValueFromPrivateConfig(this.DiagnosticsConfigurationPath, DiagnosticsHelper.EventHubElemStr, DiagnosticsHelper.EventHubSharedAccessKeyNameAttr); + var eventHubSharedAccessKey = DiagnosticsHelper.GetConfigValueFromPrivateConfig(this.DiagnosticsConfigurationPath, DiagnosticsHelper.EventHubElemStr, DiagnosticsHelper.EventHubSharedAccessKeyAttr); + + if (!string.IsNullOrEmpty(eventHubUrl) || !string.IsNullOrEmpty(eventHubSharedAccessKeyName) || !string.IsNullOrEmpty(eventHubSharedAccessKey)) + { + var privateConfigElem = privateConfig.Descendants().FirstOrDefault(d => d.Name.LocalName == DiagnosticsHelper.PrivateConfigElemStr); + XNamespace XmlNamespace = DiagnosticsHelper.XmlNamespace; + privateConfigElem.Add(new XElement(XmlNamespace + DiagnosticsHelper.EventHubElemStr, + new XAttribute(DiagnosticsHelper.EventHubUrlAttr, eventHubUrl), + new XAttribute(DiagnosticsHelper.EventHubSharedAccessKeyNameAttr, eventHubSharedAccessKeyName), + new XAttribute(DiagnosticsHelper.EventHubSharedAccessKeyAttr, eventHubSharedAccessKey) + )); + } + } } } \ 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 7bfceaf81fe5..97c738f73834 100644 --- a/src/ServiceManagement/Compute/Commands.ServiceManagement/IaaS/Extensions/Diagnostics/SetAzureVMDiagnosticsExtension.cs +++ b/src/ServiceManagement/Compute/Commands.ServiceManagement/IaaS/Extensions/Diagnostics/SetAzureVMDiagnosticsExtension.cs @@ -165,7 +165,7 @@ public override string PrivateConfiguration if (string.IsNullOrEmpty(this.privateConfiguration)) { this.privateConfiguration = JsonConvert.SerializeObject( - DiagnosticsHelper.GetPrivateDiagnosticsConfiguration(this.StorageAccountName, this.StorageAccountKey, this.StorageAccountEndpoint)); + DiagnosticsHelper.GetPrivateDiagnosticsConfiguration(this.DiagnosticsConfigurationPath, this.StorageAccountName, this.StorageAccountKey, this.StorageAccountEndpoint)); } return this.privateConfiguration;