public override void ExecuteCmdlet() { this._Helper = new AEMHelper((err) => this.WriteError(err), (msg) => this.WriteVerbose(msg), (msg) => this.WriteWarning(msg), this.CommandRuntime.Host.UI, AzureSession.Instance.ClientFactory.CreateArmClient <StorageManagementClient>(DefaultProfile.DefaultContext, AzureEnvironment.Endpoint.ResourceManager), this.DefaultContext.Subscription, this.DefaultContext.Environment.GetEndpoint(AzureEnvironment.Endpoint.StorageEndpointSuffix)); base.ExecuteCmdlet(); ExecuteClientAction(() => { VirtualMachine virtualMachine = null; if (String.IsNullOrEmpty(this.OSType)) { virtualMachine = ComputeClient.ComputeManagementClient.VirtualMachines.Get(this.ResourceGroupName, this.VMName); this.OSType = virtualMachine.StorageProfile.OsDisk.OsType.ToString(); } if (String.IsNullOrEmpty(this.OSType)) { this._Helper.WriteError("Could not determine Operating System of the VM. Please provide the Operating System type ({0} or {1}) via parameter OSType", AEMExtensionConstants.OSTypeWindows, AEMExtensionConstants.OSTypeLinux); return; } if (string.IsNullOrEmpty(this.Name)) { if (virtualMachine == null) { virtualMachine = ComputeClient.ComputeManagementClient.VirtualMachines.Get(this.ResourceGroupName, this.VMName); } var aemExtension = AEMHelper.GetAEMExtension(virtualMachine, this.OSType); if (aemExtension == null) { WriteWarning(string.Format(CultureInfo.InvariantCulture, Properties.Resources.AEMExtensionNotFound, this.ResourceGroupName, this.VMName)); return; } else { this.Name = aemExtension.Name; } } if (NoWait.IsPresent) { var op = this.VirtualMachineExtensionClient.BeginDeleteWithHttpMessagesAsync(this.ResourceGroupName, this.VMName, this.Name).GetAwaiter().GetResult(); WriteObject(ComputeAutoMapperProfile.Mapper.Map <PSAzureOperationResponse>(op)); } else { var op = this.VirtualMachineExtensionClient.DeleteWithHttpMessagesAsync(this.ResourceGroupName, this.VMName, this.Name).GetAwaiter().GetResult(); var result = ComputeAutoMapperProfile.Mapper.Map <PSAzureOperationResponse>(op); WriteObject(result); } }); }
public override void ExecuteCmdlet() { base.ExecuteCmdlet(); ExecuteClientAction(() => { if (string.IsNullOrEmpty(this.Name)) { var virtualMachine = ComputeClient.ComputeManagementClient.VirtualMachines.Get(this.ResourceGroupName, this.VMName); var osdisk = virtualMachine.StorageProfile.OsDisk; if (String.IsNullOrEmpty(this.OSType)) { this.OSType = osdisk.OsType.ToString(); } if (String.IsNullOrEmpty(this.OSType)) { WriteError("Could not determine Operating System of the VM. Please provide the Operating System type ({0} or {1}) via parameter OSType", AEMExtensionConstants.OSTypeWindows, AEMExtensionConstants.OSTypeLinux); return; } var aemExtension = AEMHelper.GetAEMExtension(virtualMachine, this.OSType); if (aemExtension == null) { WriteObject(null); return; } else { this.Name = aemExtension.Name; } } AzureOperationResponse <VirtualMachineExtension> virtualMachineExtensionGetResponse = null; if (Status.IsPresent) { virtualMachineExtensionGetResponse = this.VirtualMachineExtensionClient.GetWithInstanceView(this.ResourceGroupName, this.VMName, this.Name); } else { virtualMachineExtensionGetResponse = this.VirtualMachineExtensionClient.GetWithHttpMessagesAsync( this.ResourceGroupName, this.VMName, this.Name).GetAwaiter().GetResult(); } var returnedExtension = virtualMachineExtensionGetResponse.ToPSVirtualMachineExtension( this.ResourceGroupName, this.VMName); WriteObject(returnedExtension); }); }
public override void ExecuteCmdlet() { this._Helper = new AEMHelper((err) => this.WriteError(err), (msg) => this.WriteVerbose(msg), (msg) => this.WriteWarning(msg), this.CommandRuntime.Host.UI, AzureSession.Instance.ClientFactory.CreateArmClient <StorageManagementClient>(DefaultProfile.DefaultContext, AzureEnvironment.Endpoint.ResourceManager), this.DefaultContext.Subscription); base.ExecuteCmdlet(); ExecuteClientAction(() => { this._Helper.WriteVerbose("Retrieving VM..."); var selectedVM = ComputeClient.ComputeManagementClient.VirtualMachines.Get(this.ResourceGroupName, this.VMName); var selectedVMStatus = ComputeClient.ComputeManagementClient.VirtualMachines.GetWithInstanceView(this.ResourceGroupName, this.VMName).Body.InstanceView; if (selectedVM == null) { var subscriptionId = this.DefaultContext.Subscription.Id; this._Helper.WriteError("No virtual machine with name {0} in resource group {1} in subscription {2} found", this.VMName, this.ResourceGroupName, subscriptionId); return; } var osdisk = selectedVM.StorageProfile.OsDisk; if (String.IsNullOrEmpty(this.OSType)) { this.OSType = osdisk.OsType.ToString(); } if (String.IsNullOrEmpty(this.OSType)) { this._Helper.WriteError("Could not determine Operating System of the VM. Please provide the Operating System type ({0} or {1}) via parameter OSType", AEMExtensionConstants.OSTypeWindows, AEMExtensionConstants.OSTypeLinux); return; } var disks = selectedVM.StorageProfile.DataDisks; var sapmonPublicConfig = new List <KeyValuePair>(); var sapmonPrivateConfig = new List <KeyValuePair>(); var cpuOvercommit = 0; var memOvercommit = 0; var vmsize = selectedVM.HardwareProfile.VmSize; switch (vmsize) { case AEMExtensionConstants.VMSizeExtraSmall: case AEMExtensionConstants.VMSizeStandard_A0: case AEMExtensionConstants.VMSizeBasic_A0: vmsize = "ExtraSmall (A0)"; WriteVerbose("VM Size is ExtraSmall - setting overcommitted setting"); cpuOvercommit = 1; break; case "Small": vmsize = "Small (A1)"; break; case "Medium": vmsize = "Medium (A2)"; break; case "Large": vmsize = "Large (A3)"; break; case "ExtraLarge": vmsize = "ExtraLarge (A4)"; break; } sapmonPublicConfig.Add(new KeyValuePair() { Key = "vmsize", Value = vmsize }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "vm.role", Value = "IaaS" }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "vm.memory.isovercommitted", Value = memOvercommit }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "vm.cpu.isovercommitted", Value = cpuOvercommit }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "script.version", Value = AEMExtensionConstants.CurrentScriptVersion }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "verbose", Value = "0" }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "href", Value = "http://aka.ms/sapaem" }); var vmSLA = this._Helper.GetVMSLA(selectedVM); if (vmSLA.HasSLA) { sapmonPublicConfig.Add(new KeyValuePair() { Key = "vm.sla.throughput", Value = vmSLA.TP }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "vm.sla.iops", Value = vmSLA.IOPS }); } // Get Disks var accounts = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase); if (osdisk.ManagedDisk == null) { var accountName = this._Helper.GetStorageAccountFromUri(osdisk.Vhd.Uri); var storageKey = this._Helper.GetAzureStorageKeyFromCache(accountName); accounts.Add(accountName, storageKey); this._Helper.WriteHost("[INFO] Adding configuration for OS disk"); var caching = osdisk.Caching; sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.name", Value = this._Helper.GetDiskName(osdisk.Vhd.Uri) }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.caching", Value = caching }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.account", Value = accountName }); if (this._Helper.IsPremiumStorageAccount(accountName)) { WriteVerbose("OS Disk Storage Account is a premium account - adding SLAs for OS disk"); var sla = this._Helper.GetDiskSLA(osdisk); sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.type", Value = AEMExtensionConstants.DISK_TYPE_PREMIUM }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.sla.throughput", Value = sla.TP }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.sla.iops", Value = sla.IOPS }); } else { WriteVerbose("OS Disk Storage Account is a standard account"); sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.type", Value = AEMExtensionConstants.DISK_TYPE_STANDARD }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.connminute", Value = (accountName + ".minute") }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.connhour", Value = (accountName + ".hour") }); } } else { var osDiskMD = ComputeClient.ComputeManagementClient.Disks.Get(this._Helper.GetResourceGroupFromId(osdisk.ManagedDisk.Id), this._Helper.GetResourceNameFromId(osdisk.ManagedDisk.Id)); if (osDiskMD.Sku.Name == StorageAccountTypes.PremiumLRS) { WriteVerbose("OS Disk Storage Account is a premium account - adding SLAs for OS disk"); var sla = this._Helper.GetDiskSLA(osDiskMD.DiskSizeGB, null); var caching = osdisk.Caching; sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.name", Value = this._Helper.GetResourceNameFromId(osdisk.ManagedDisk.Id) }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.caching", Value = caching }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.type", Value = AEMExtensionConstants.DISK_TYPE_PREMIUM_MD }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.sla.throughput", Value = sla.TP }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "osdisk.sla.iops", Value = sla.IOPS }); } else { this._Helper.WriteWarning("[WARN] Standard Managed Disks are not supported. Extension will be installed but no disk metrics will be available."); } } // Get Storage accounts from disks var diskNumber = 1; foreach (var disk in disks) { if (disk.ManagedDisk != null) { var diskMD = ComputeClient.ComputeManagementClient.Disks.Get(this._Helper.GetResourceGroupFromId(disk.ManagedDisk.Id), this._Helper.GetResourceNameFromId(disk.ManagedDisk.Id)); if (diskMD.Sku.Name == StorageAccountTypes.PremiumLRS) { this._Helper.WriteVerbose("Data Disk {0} is a Premium Managed Disk - adding SLAs for disk", diskNumber.ToString()); var sla = this._Helper.GetDiskSLA(diskMD.DiskSizeGB, null); var cachingMD = disk.Caching; sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.lun." + diskNumber, Value = disk.Lun }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.name." + diskNumber, Value = this._Helper.GetResourceNameFromId(disk.ManagedDisk.Id) }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.caching." + diskNumber, Value = cachingMD }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.type." + diskNumber, Value = AEMExtensionConstants.DISK_TYPE_PREMIUM_MD }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.sla.throughput." + diskNumber, Value = sla.TP }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.sla.iops." + diskNumber, Value = sla.IOPS }); this._Helper.WriteVerbose("Done - Data Disk {0} is a Premium Managed Disk - adding SLAs for disk", diskNumber.ToString()); } else { this._Helper.WriteWarning("[WARN] Standard Managed Disks are not supported. Extension will be installed but no disk metrics will be available."); } } else { var accountName = this._Helper.GetStorageAccountFromUri(disk.Vhd.Uri); if (!accounts.ContainsKey(accountName)) { var storageKey = this._Helper.GetAzureStorageKeyFromCache(accountName); accounts.Add(accountName, storageKey); } this._Helper.WriteHost("[INFO] Adding configuration for data disk {0}", disk.Name); var caching = disk.Caching; sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.lun." + diskNumber, Value = disk.Lun }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.name." + diskNumber, Value = this._Helper.GetDiskName(disk.Vhd.Uri) }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.caching." + diskNumber, Value = caching }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.account." + diskNumber, Value = accountName }); if (this._Helper.IsPremiumStorageAccount(accountName)) { this._Helper.WriteVerbose("Data Disk {0} Storage Account is a premium account - adding SLAs for disk", diskNumber.ToString()); var sla = this._Helper.GetDiskSLA(disk); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.type." + diskNumber, Value = AEMExtensionConstants.DISK_TYPE_PREMIUM }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.sla.throughput." + diskNumber, Value = sla.TP }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.sla.iops." + diskNumber, Value = sla.IOPS }); this._Helper.WriteVerbose("Done - Data Disk {0} Storage Account is a premium account - adding SLAs for disk", diskNumber.ToString()); } else { sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.type." + diskNumber, Value = AEMExtensionConstants.DISK_TYPE_STANDARD }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.connminute." + diskNumber, Value = (accountName + ".minute") }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "disk.connhour." + diskNumber, Value = (accountName + ".hour") }); } } diskNumber += 1; } //Check storage accounts for analytics foreach (var account in accounts) { this._Helper.WriteVerbose("Testing Storage Metrics for {0}", account.Key); var storage = this._Helper.GetStorageAccountFromCache(account.Key); if (!this._Helper.IsPremiumStorageAccount(storage)) { if (!this.SkipStorage.IsPresent) { var currentConfig = this._Helper.GetStorageAnalytics(storage.Name); if (!this._Helper.CheckStorageAnalytics(storage.Name, currentConfig)) { this._Helper.WriteHost("[INFO] Enabling Storage Account Metrics for storage account {0}", storage.Name); // Enable analytics on storage accounts this.SetStorageAnalytics(storage.Name); } } var endpoint = this._Helper.GetAzureSAPTableEndpoint(storage); var hourUri = endpoint + "$MetricsHourPrimaryTransactionsBlob"; var minuteUri = endpoint + "$MetricsMinutePrimaryTransactionsBlob"; this._Helper.WriteHost("[INFO] Adding Storage Account Metric information for storage account {0}", storage.Name); sapmonPrivateConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".hour.key"), Value = account.Value }); sapmonPrivateConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".minute.key"), Value = account.Value }); sapmonPublicConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".hour.uri"), Value = hourUri }); sapmonPublicConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".minute.uri"), Value = minuteUri }); sapmonPublicConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".hour.name"), Value = storage.Name }); sapmonPublicConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".minute.name"), Value = storage.Name }); } else { this._Helper.WriteHost("[INFO] {0} is of type {1} - Storage Account Metrics are not available for Premium Type Storage.", storage.Name, storage.SkuName()); sapmonPublicConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".hour.ispremium"), Value = 1 }); sapmonPublicConfig.Add(new KeyValuePair() { Key = ((storage.Name) + ".minute.ispremium"), Value = 1 }); } } WriteVerbose("Chechking if WAD needs to be configured"); // Enable VM Diagnostics if (this.EnableWAD.IsPresent) { this._Helper.WriteHost("[INFO] Enabling IaaSDiagnostics for VM {0}", selectedVM.Name); KeyValuePair wadstorage = null; if (String.IsNullOrEmpty(this.WADStorageAccountName)) { KeyValuePair <string, string>?wadstorageTemp = accounts.Cast <KeyValuePair <string, string>?>(). FirstOrDefault(accTemp => !this._Helper.IsPremiumStorageAccount(accTemp.Value.Key)); if (wadstorageTemp.HasValue) { wadstorage = new KeyValuePair(wadstorageTemp.Value.Key, wadstorageTemp.Value.Value); } } else { wadstorage = new KeyValuePair(this.WADStorageAccountName, this._Helper.GetAzureStorageKeyFromCache(WADStorageAccountName)); } if (wadstorage == null) { this._Helper.WriteError("A standard storage account is required. Please use parameter WADStorageAccountName to specify a standard storage account you want to use for this VM."); return; } selectedVM = SetAzureVMDiagnosticsExtensionC(selectedVM, selectedVMStatus, wadstorage.Key, wadstorage.Value as string); var storage = this._Helper.GetStorageAccountFromCache(wadstorage.Key); var endpoint = this._Helper.GetAzureSAPTableEndpoint(storage); var wadUri = endpoint + AEMExtensionConstants.WadTableName; sapmonPrivateConfig.Add(new KeyValuePair() { Key = "wad.key", Value = wadstorage.Value }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "wad.name", Value = wadstorage.Key }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "wad.isenabled", Value = 1 }); sapmonPublicConfig.Add(new KeyValuePair() { Key = "wad.uri", Value = wadUri }); } else { sapmonPublicConfig.Add(new KeyValuePair() { Key = "wad.isenabled", Value = 0 }); } ExtensionConfig jsonPublicConfig = new ExtensionConfig(); jsonPublicConfig.Config = sapmonPublicConfig; ExtensionConfig jsonPrivateConfig = new ExtensionConfig(); jsonPrivateConfig.Config = sapmonPrivateConfig; this._Helper.WriteHost("[INFO] Updating Azure Enhanced Monitoring Extension for SAP configuration - Please wait..."); WriteVerbose("Installing AEM extension"); Version aemVersion = this._Helper.GetExtensionVersion(selectedVM, selectedVMStatus, OSType, AEMExtensionConstants.AEMExtensionType[OSType], AEMExtensionConstants.AEMExtensionPublisher[OSType]); var op = this.VirtualMachineExtensionClient.CreateOrUpdateWithHttpMessagesAsync( this.ResourceGroupName, this.VMName, AEMExtensionConstants.AEMExtensionDefaultName[OSType], new VirtualMachineExtension() { Publisher = AEMExtensionConstants.AEMExtensionPublisher[OSType], VirtualMachineExtensionType = AEMExtensionConstants.AEMExtensionType[OSType], TypeHandlerVersion = aemVersion.ToString(2), Settings = jsonPublicConfig, ProtectedSettings = jsonPrivateConfig, Location = selectedVM.Location, AutoUpgradeMinorVersion = true, ForceUpdateTag = DateTime.Now.Ticks.ToString() }).GetAwaiter().GetResult(); this._Helper.WriteHost("[INFO] Azure Enhanced Monitoring Extension for SAP configuration updated. It can take up to 15 Minutes for the monitoring data to appear in the SAP system."); this._Helper.WriteHost("[INFO] You can check the configuration of a virtual machine by calling the Test-AzureRmVMAEMExtension commandlet."); var result = ComputeAutoMapperProfile.Mapper.Map <PSAzureOperationResponse>(op); WriteObject(result); }); }
public void TestScopePermissionCheck() { string groupScope = "group"; string resourceScope = "resource"; // | Permissions for RG | Permission for Resource (after check) | Result | // | Y | Y | Y | { bool expectedCheckResult = true; bool expectedGroupCall = false; bool expectedResCall = false; int okCount = 0; int nokCount = 0; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(true, true, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(true); } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } // | Permissions for RG | Permission for Resource (after check) | Result | // | Y | N | Y | { bool expectedCheckResult = true; bool expectedGroupCall = false; bool expectedResCall = false; int okCount = 0; int nokCount = 0; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(true, false, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(true); } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } // | Permissions for RG | Permission for Resource (after check) | Result | // | Y | ? | Y | { bool expectedCheckResult = true; bool expectedGroupCall = false; bool expectedResCall = false; int okCount = 0; int nokCount = 0; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(true, null, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(true); } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } // | Permissions for RG | Permission for Resource (after check) | Result | // | N | Y | Y | { bool expectedCheckResult = true; bool expectedGroupCall = false; bool expectedResCall = false; int okCount = 0; int nokCount = 0; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(false, true, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(true); } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } // | Permissions for RG | Permission for Resource (after check) | Result | // | N | N | N | { bool expectedCheckResult = false; bool expectedGroupCall = false; bool expectedResCall = false; int okCount = 0; int nokCount = 0; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(false, false, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(true); } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } // | Permissions for RG | Permission for Resource (after check) | Result | // | N | ? (Y) | check resource (Y) | { bool expectedCheckResult = true; bool expectedGroupCall = false; bool expectedResCall = true; int okCount = 1; int nokCount = 0; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(false, null, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(true); } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } // | Permissions for RG | Permission for Resource (after check) | Result | // | N | ? (N) | check resource (N) | { bool expectedCheckResult = false; bool expectedGroupCall = false; bool expectedResCall = true; int okCount = 0; int nokCount = 1; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(false, null, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(false); } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } // | Permissions for RG | Permission for Resource (after check) | Result | // | ? | Y | Y | { bool expectedCheckResult = true; bool expectedGroupCall = false; bool expectedResCall = false; int okCount = 0; int nokCount = 0; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(null, true, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(true); } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } // | Permissions for RG | Permission for Resource (after check) | Result | // | ? (Y) | N | check resource group (Y) | { bool expectedCheckResult = true; bool expectedGroupCall = true; bool expectedResCall = false; int okCount = 1; int nokCount = 0; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(null, false, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(true); } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } // | Permissions for RG | Permission for Resource (after check) | Result | // | ? (N) | N | check resource group (N) | { bool expectedCheckResult = false; bool expectedGroupCall = true; bool expectedResCall = false; int okCount = 0; int nokCount = 1; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(null, false, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(false); } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } // | Permissions for RG | Permission for Resource (after check) | Result | // | ? (Y) | ? | check resource group, if no, check resource (Y) | { bool expectedCheckResult = true; bool expectedGroupCall = true; bool expectedResCall = false; int okCount = 1; int nokCount = 0; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(null, null, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(true); } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } // | Permissions for RG | Permission for Resource (after check) | Result | // | ? (N) | ? (Y) | check resource group, if no, check resource (N)(Y) | { bool expectedCheckResult = true; bool expectedGroupCall = true; bool expectedResCall = true; int okCount = 1; int nokCount = 1; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(null, null, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(scope == resourceScope); // return true for resource scope } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } // | Permissions for RG | Permission for Resource (after check) | Result | // | ? (N) | ? (N) | check resource group, if no, check resource (N)(N) | { bool expectedCheckResult = false; bool expectedGroupCall = true; bool expectedResCall = true; int okCount = 0; int nokCount = 2; HashSet <string> ok = new HashSet <string>(); HashSet <string> nok = new HashSet <string>(); bool groupCalled = false; bool resCalled = false; bool checkOk = AEMHelper.CheckScopePermissions(null, null, groupScope, resourceScope, "role", null, ok, nok, (scope, roleDefinitionId, vm) => { groupCalled |= scope == groupScope; resCalled |= scope == resourceScope; return(false); } ); Assert.True(checkOk == expectedCheckResult); Assert.True(groupCalled == expectedGroupCall); Assert.True(resCalled == expectedResCall); Assert.True(ok.Count == okCount); Assert.True(nok.Count == nokCount); } }
public override void ExecuteCmdlet() { this._Helper = new AEMHelper((err) => this.WriteError(err), (msg) => this.WriteVerbose(msg), (msg) => this.WriteWarning(msg), this.CommandRuntime.Host.UI, AzureSession.ClientFactory.CreateClient <StorageManagementClient>(DefaultProfile.Context, AzureEnvironment.Endpoint.ResourceManager), this.DefaultContext.Subscription); this._Helper.WriteVerbose("Starting TestAzureRmVMAEMExtension"); base.ExecuteCmdlet(); ExecuteClientAction(() => { AEMTestResult rootResult = new AEMTestResult(); rootResult.TestName = "Azure Enhanced Monitoring Test"; //################################################# //# Check if VM exists //################################################# this._Helper.WriteHost("VM Existance check for {0} ...", false, this.VMName); var selectedVM = this.ComputeClient.ComputeManagementClient.VirtualMachines.Get(this.ResourceGroupName, this.VMName); var selectedVMStatus = this.ComputeClient.ComputeManagementClient.VirtualMachines.GetWithInstanceView(this.ResourceGroupName, this.VMName).Body.InstanceView; if (selectedVM == null) { rootResult.PartialResults.Add(new AEMTestResult("VM Existance check for {0}", false, this.VMName)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); return; } else { rootResult.PartialResults.Add(new AEMTestResult("VM Existance check for {0}", true, this.VMName)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } //################################################# //################################################# var osdisk = selectedVM.StorageProfile.OsDisk; if (String.IsNullOrEmpty(this.OSType)) { this.OSType = osdisk.OsType.ToString(); } if (String.IsNullOrEmpty(this.OSType)) { this._Helper.WriteError("Could not determine Operating System of the VM. Please provide the Operating System type ({0} or {1}) via parameter OSType", AEMExtensionConstants.OSTypeWindows, AEMExtensionConstants.OSTypeLinux); return; } //################################################# //# Check for Guest Agent //################################################# this._Helper.WriteHost("VM Guest Agent check...", false); var vmAgentStatus = false; //# It is not possible to detect if VM Agent is installed on ARM vmAgentStatus = true; if (!vmAgentStatus) { rootResult.PartialResults.Add(new AEMTestResult("VM Guest Agent check", false)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); this._Helper.WriteWarning(AEMExtensionConstants.MissingGuestAgentWarning); return; } else { rootResult.PartialResults.Add(new AEMTestResult("VM Guest Agent check", true)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } //################################################# //################################################# //################################################# //# Check for Azure Enhanced Monitoring Extension for SAP //################################################# this._Helper.WriteHost("Azure Enhanced Monitoring Extension for SAP Installation check...", false); string monPublicConfig = null; var monExtension = this._Helper.GetExtension(selectedVM, AEMExtensionConstants.AEMExtensionType[this.OSType], AEMExtensionConstants.AEMExtensionPublisher[this.OSType]); if (monExtension != null) { monPublicConfig = monExtension.Settings.ToString(); } if (monExtension == null || String.IsNullOrEmpty(monPublicConfig)) { rootResult.PartialResults.Add(new AEMTestResult("Azure Enhanced Monitoring Extension for SAP Installation check", false)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } else { rootResult.PartialResults.Add(new AEMTestResult("Azure Enhanced Monitoring Extension for SAP Installation check", true)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } //################################################# //################################################# var accounts = new List <string>(); //var osdisk = selectedVM.StorageProfile.OsDisk; var dataDisks = selectedVM.StorageProfile.DataDisks; var accountName = this._Helper.GetStorageAccountFromUri(osdisk.Vhd.Uri); var osaccountName = accountName; accounts.Add(accountName); foreach (var disk in dataDisks) { accountName = this._Helper.GetStorageAccountFromUri(disk.Vhd.Uri); if (!accounts.Contains(accountName)) { accounts.Add(accountName); } } //################################################# //# Check storage metrics //################################################# this._Helper.WriteHost("Storage Metrics check..."); var metricsResult = new AEMTestResult("Storage Metrics check"); rootResult.PartialResults.Add(metricsResult); if (!this.SkipStorageCheck.IsPresent) { foreach (var account in accounts) { var accountResult = new AEMTestResult("Storage Metrics check for {0}", account); metricsResult.PartialResults.Add(accountResult); this._Helper.WriteHost("\tStorage Metrics check for {0}...", account); var storage = this._Helper.GetStorageAccountFromCache(account); if (!this._Helper.IsPremiumStorageAccount(storage)) { this._Helper.WriteHost("\t\tStorage Metrics configuration check for {0}...", false, account); var currentConfig = this._Helper.GetStorageAnalytics(account); bool storageConfigOk = false; if (!this._Helper.CheckStorageAnalytics(account, currentConfig)) { accountResult.PartialResults.Add(new AEMTestResult("Storage Metrics configuration check for {0}", false, account)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } else { accountResult.PartialResults.Add(new AEMTestResult("Storage Metrics configuration check for {0}", true, account)); this._Helper.WriteHost("OK ", ConsoleColor.Green); storageConfigOk = true; } this._Helper.WriteHost("\t\tStorage Metrics data check for {0}...", false, account); var filterMinute = Microsoft.WindowsAzure.Storage.Table.TableQuery. GenerateFilterConditionForDate("Timestamp", "gt", DateTime.Now.AddMinutes(AEMExtensionConstants.ContentAgeInMinutes * -1)); if (storageConfigOk && this._Helper.CheckTableAndContent(account, "$MetricsMinutePrimaryTransactionsBlob", filterMinute, ".", false, this.WaitTimeInMinutes)) { this._Helper.WriteHost("OK ", ConsoleColor.Green); accountResult.PartialResults.Add(new AEMTestResult("Storage Metrics data check for {0}", true, account)); } else { accountResult.PartialResults.Add(new AEMTestResult("Storage Metrics data check for {0}", false, account)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } } else { accountResult.PartialResults.Add(new AEMTestResult("Storage Metrics not available for Premium Storage account {0}", true, account)); this._Helper.WriteHost("\t\tStorage Metrics not available for Premium Storage account {0}...", false, account); this._Helper.WriteHost("OK ", ConsoleColor.Green); } } } else { metricsResult.Result = true; this._Helper.WriteHost("Skipped ", ConsoleColor.Yellow); } //################################################# //################################################# //################################################# //# Check Azure Enhanced Monitoring Extension for SAP Configuration //################################################# this._Helper.WriteHost("Azure Enhanced Monitoring Extension for SAP public configuration check...", false); var aemConfigResult = new AEMTestResult("Azure Enhanced Monitoring Extension for SAP public configuration check"); rootResult.PartialResults.Add(aemConfigResult); JObject sapmonPublicConfig = null; if (monExtension != null) { this._Helper.WriteHost(""); //New Line sapmonPublicConfig = JsonConvert.DeserializeObject(monPublicConfig) as JObject; var storage = this._Helper.GetStorageAccountFromCache(osaccountName); var osaccountIsPremium = this._Helper.IsPremiumStorageAccount(osaccountName); var vmSize = selectedVM.HardwareProfile.VmSize; this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Size", "vmsize", sapmonPublicConfig, vmSize, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Memory", "vm.memory.isovercommitted", sapmonPublicConfig, 0, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM CPU", "vm.cpu.isovercommitted", sapmonPublicConfig, 0, aemConfigResult); this._Helper.MonitoringPropertyExists("Azure Enhanced Monitoring Extension for SAP public configuration check: Script Version", "script.version", sapmonPublicConfig, aemConfigResult); var vmSLA = this._Helper.GetVMSLA(selectedVM); if (vmSLA.HasSLA) { this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM SLA IOPS", "vm.sla.iops", sapmonPublicConfig, vmSLA.IOPS, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM SLA Throughput", "vm.sla.throughput", sapmonPublicConfig, vmSLA.TP, aemConfigResult); } int wadEnabled; if (this._Helper.GetMonPropertyValue("wad.isenabled", sapmonPublicConfig, out wadEnabled)) { if (wadEnabled == 1) { this._Helper.MonitoringPropertyExists("Azure Enhanced Monitoring Extension for SAP public configuration check: WAD name", "wad.name", sapmonPublicConfig, aemConfigResult); this._Helper.MonitoringPropertyExists("Azure Enhanced Monitoring Extension for SAP public configuration check: WAD URI", "wad.uri", sapmonPublicConfig, aemConfigResult); } else { this._Helper.MonitoringPropertyExists("Azure Enhanced Monitoring Extension for SAP public configuration check: WAD name", "wad.name", sapmonPublicConfig, aemConfigResult, false); this._Helper.MonitoringPropertyExists("Azure Enhanced Monitoring Extension for SAP public configuration check: WAD URI", "wad.uri", sapmonPublicConfig, aemConfigResult, false); } } else { string message = "Azure Enhanced Monitoring Extension for SAP public configuration check:"; aemConfigResult.PartialResults.Add(new AEMTestResult(message, false)); this._Helper.WriteHost(message + "...", false); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } if (!osaccountIsPremium) { var endpoint = this._Helper.GetAzureSAPTableEndpoint(storage); var minuteUri = endpoint + "$MetricsMinutePrimaryTransactionsBlob"; this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS disk URI Key", "osdisk.connminute", sapmonPublicConfig, osaccountName + ".minute", aemConfigResult); //# TODO: check uri config this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS disk URI Value", osaccountName + ".minute.uri", sapmonPublicConfig, minuteUri, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS disk URI Name", osaccountName + ".minute.name", sapmonPublicConfig, osaccountName, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS Disk Type", "osdisk.type", sapmonPublicConfig, AEMExtensionConstants.DISK_TYPE_STANDARD, aemConfigResult); } else { var sla = this._Helper.GetDiskSLA(osdisk); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS Disk Type", "osdisk.type", sapmonPublicConfig, AEMExtensionConstants.DISK_TYPE_PREMIUM, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS Disk SLA IOPS", "osdisk.sla.throughput", sapmonPublicConfig, sla.TP, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS Disk SLA Throughput", "osdisk.sla.iops", sapmonPublicConfig, sla.IOPS, aemConfigResult); } this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS disk name", "osdisk.name", sapmonPublicConfig, this._Helper.GetDiskName(osdisk.Vhd.Uri), aemConfigResult); var diskNumber = 1; foreach (var disk in dataDisks) { accountName = this._Helper.GetStorageAccountFromUri(disk.Vhd.Uri); storage = this._Helper.GetStorageAccountFromCache(accountName); var accountIsPremium = this._Helper.IsPremiumStorageAccount(storage); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " LUN", "disk.lun." + diskNumber, sapmonPublicConfig, disk.Lun, aemConfigResult); if (!accountIsPremium) { var endpoint = this._Helper.GetAzureSAPTableEndpoint(storage); var minuteUri = endpoint + "$MetricsMinutePrimaryTransactionsBlob"; this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " URI Key", "disk.connminute." + diskNumber, sapmonPublicConfig, accountName + ".minute", aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " URI Value", accountName + ".minute.uri", sapmonPublicConfig, minuteUri, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " URI Name", accountName + ".minute.name", sapmonPublicConfig, accountName, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " Type", "disk.type." + diskNumber, sapmonPublicConfig, AEMExtensionConstants.DISK_TYPE_STANDARD, aemConfigResult); } else { var sla = this._Helper.GetDiskSLA(disk); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " Type", "disk.type." + diskNumber, sapmonPublicConfig, AEMExtensionConstants.DISK_TYPE_PREMIUM, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " SLA IOPS", "disk.sla.throughput." + diskNumber, sapmonPublicConfig, sla.TP, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " SLA Throughput", "disk.sla.iops." + diskNumber, sapmonPublicConfig, sla.IOPS, aemConfigResult); } this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " name", "disk.name." + diskNumber, sapmonPublicConfig, this._Helper.GetDiskName(disk.Vhd.Uri), aemConfigResult); diskNumber += 1; } if (dataDisks.Count == 0) { aemConfigResult.PartialResults.Add(new AEMTestResult("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disks", true)); this._Helper.WriteHost("\tAzure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disks ", false); this._Helper.WriteHost("OK ", ConsoleColor.Green); } } else { aemConfigResult.Result = false; this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } //################################################# //################################################# //################################################# //# Check WAD Configuration //################################################# int iswadEnabled; if (this._Helper.GetMonPropertyValue("wad.isenabled", sapmonPublicConfig, out iswadEnabled) && iswadEnabled == 1) { var wadConfigResult = new AEMTestResult("IaaSDiagnostics check"); rootResult.PartialResults.Add(wadConfigResult); string wadPublicConfig = null; var wadExtension = this._Helper.GetExtension(selectedVM, AEMExtensionConstants.WADExtensionType[this.OSType], AEMExtensionConstants.WADExtensionPublisher[this.OSType]); if (wadExtension != null) { wadPublicConfig = wadExtension.Settings.ToString(); } this._Helper.WriteHost("IaaSDiagnostics check...", false); if (wadExtension != null) { this._Helper.WriteHost(""); //New Line this._Helper.WriteHost("\tIaaSDiagnostics configuration check...", false); var currentJSONConfig = JsonConvert.DeserializeObject(wadPublicConfig) as Newtonsoft.Json.Linq.JObject; var base64 = currentJSONConfig["xmlCfg"] as Newtonsoft.Json.Linq.JValue; System.Xml.XmlDocument currentConfig = new System.Xml.XmlDocument(); currentConfig.LoadXml(Encoding.UTF8.GetString(System.Convert.FromBase64String(base64.Value.ToString()))); if (!this._Helper.CheckWADConfiguration(currentConfig)) { wadConfigResult.PartialResults.Add(new AEMTestResult("IaaSDiagnostics configuration check", false)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } else { wadConfigResult.PartialResults.Add(new AEMTestResult("IaaSDiagnostics configuration check", true)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } this._Helper.WriteHost("\tIaaSDiagnostics performance counters check..."); var wadPerfCountersResult = new AEMTestResult("IaaSDiagnostics performance counters check"); wadConfigResult.PartialResults.Add(wadPerfCountersResult); foreach (var perfCounter in AEMExtensionConstants.PerformanceCounters[this.OSType]) { this._Helper.WriteHost("\t\tIaaSDiagnostics performance counters " + (perfCounter.counterSpecifier) + "check...", false); var currentCounter = currentConfig.SelectSingleNode("/WadCfg/DiagnosticMonitorConfiguration/PerformanceCounters/PerformanceCounterConfiguration[@counterSpecifier = '" + perfCounter.counterSpecifier + "']"); if (currentCounter != null) { wadPerfCountersResult.PartialResults.Add(new AEMTestResult("IaaSDiagnostics performance counters " + (perfCounter.counterSpecifier) + "check...", true)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } else { wadPerfCountersResult.PartialResults.Add(new AEMTestResult("IaaSDiagnostics performance counters " + (perfCounter.counterSpecifier) + "check...", false)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } } string wadstorage; if (!this._Helper.GetMonPropertyValue <string>("wad.name", sapmonPublicConfig, out wadstorage)) { wadstorage = null; } this._Helper.WriteHost("\tIaaSDiagnostics data check...", false); var deploymentId = String.Empty; var roleName = String.Empty; var extStatuses = this._Helper.GetExtension(selectedVM, selectedVMStatus, AEMExtensionConstants.AEMExtensionType[this.OSType], AEMExtensionConstants.AEMExtensionPublisher[this.OSType]); InstanceViewStatus aemStatus = null; if (extStatuses != null && extStatuses.Statuses != null) { aemStatus = extStatuses.Statuses.FirstOrDefault(stat => Regex.Match(stat.Message, "deploymentId=(\\S*) roleInstance=(\\S*)").Success); } if (aemStatus != null) { var match = Regex.Match(aemStatus.Message, "deploymentId=(\\S*) roleInstance=(\\S*)"); deploymentId = match.Groups[1].Value; roleName = match.Groups[2].Value; } else { this._Helper.WriteWarning("DeploymentId and RoleInstanceName could not be parsed from extension status"); } var ok = false; if (!this.SkipStorageCheck.IsPresent && (!String.IsNullOrEmpty(deploymentId)) && (!String.IsNullOrEmpty(roleName)) && (!String.IsNullOrEmpty(wadstorage))) { if (this.OSType.Equals(AEMExtensionConstants.OSTypeLinux, StringComparison.InvariantCultureIgnoreCase)) { ok = this._Helper.CheckDiagnosticsTable(wadstorage, deploymentId, selectedVM.OsProfile.ComputerName, ".", this.OSType, this.WaitTimeInMinutes); } else { string filterMinute = "Role eq '" + AEMExtensionConstants.ROLECONTENT + "' and DeploymentId eq '" + deploymentId + "' and RoleInstance eq '" + roleName + "' and PartitionKey gt '0" + DateTime.UtcNow.AddMinutes(AEMExtensionConstants.ContentAgeInMinutes * -1).Ticks + "'"; ok = this._Helper.CheckTableAndContent(wadstorage, AEMExtensionConstants.WadTableName, filterMinute, ".", false, this.WaitTimeInMinutes); } } if (ok && !this.SkipStorageCheck.IsPresent) { wadConfigResult.PartialResults.Add(new AEMTestResult("IaaSDiagnostics data check", true)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } else if (!this.SkipStorageCheck.IsPresent) { wadConfigResult.PartialResults.Add(new AEMTestResult("IaaSDiagnostics data check", false)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } else { this._Helper.WriteHost("Skipped ", ConsoleColor.Yellow); } } else { wadConfigResult.Result = false; this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } } //################################################# //################################################# if (!rootResult.Result) { this._Helper.WriteHost("The script found some configuration issues. Please run the Set-AzureRmVMExtension commandlet to update the configuration of the virtual machine!"); } this._Helper.WriteVerbose("TestAzureRmVMAEMExtension Done (" + rootResult.Result + ")"); var result = Mapper.Map <AEMTestResult>(rootResult); WriteObject(result); }); }
private VirtualMachine SetAzureVMDiagnosticsExtensionC(VirtualMachine vm, VirtualMachineInstanceView vmStatus, string storageAccountName, string storageAccountKey) { System.Xml.XmlDocument xpublicConfig = null; var extensionName = AEMExtensionConstants.WADExtensionDefaultName[this.OSType]; var extTemp = AEMHelper.GetAEMExtension(vm, this.OSType); object publicConf = null; if (extTemp != null) { publicConf = extTemp.Settings; extensionName = extTemp.Name; } if (publicConf != null) { var jpublicConf = publicConf as Newtonsoft.Json.Linq.JObject; if (jpublicConf == null) { throw new ArgumentException(); } var base64 = jpublicConf["xmlCfg"] as Newtonsoft.Json.Linq.JValue; if (base64 == null) { throw new ArgumentException(); } System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument(); xDoc.LoadXml(Encoding.UTF8.GetString(System.Convert.FromBase64String(base64.Value.ToString()))); if (xDoc.SelectSingleNode("/WadCfg/DiagnosticMonitorConfiguration/PerformanceCounters") != null) { xDoc.SelectSingleNode("WadCfg/DiagnosticMonitorConfiguration").Attributes["overallQuotaInMB"].Value = "4096"; xDoc.SelectSingleNode("WadCfg/DiagnosticMonitorConfiguration/PerformanceCounters").Attributes["scheduledTransferPeriod"].Value = "PT1M"; xpublicConfig = xDoc; } } if (xpublicConfig == null) { xpublicConfig = new System.Xml.XmlDocument(); xpublicConfig.LoadXml(AEMExtensionConstants.WADConfigXML); } foreach (var perfCounter in AEMExtensionConstants.PerformanceCounters[OSType]) { var currentCounter = xpublicConfig. SelectSingleNode("WadCfg/DiagnosticMonitorConfiguration/PerformanceCounters/PerformanceCounterConfiguration[@counterSpecifier = '" + perfCounter.counterSpecifier + "']"); if (currentCounter == null) { var node = xpublicConfig.CreateElement("PerformanceCounterConfiguration"); xpublicConfig.SelectSingleNode("WadCfg/DiagnosticMonitorConfiguration/PerformanceCounters").AppendChild(node); node.SetAttribute("counterSpecifier", perfCounter.counterSpecifier); node.SetAttribute("sampleRate", perfCounter.sampleRate); } } var endpoint = this._Helper.GetCoreEndpoint(storageAccountName); endpoint = "https://" + endpoint; Newtonsoft.Json.Linq.JObject jPublicConfig = new Newtonsoft.Json.Linq.JObject(); jPublicConfig.Add("xmlCfg", new Newtonsoft.Json.Linq.JValue(System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(xpublicConfig.InnerXml)))); Newtonsoft.Json.Linq.JObject jPrivateConfig = new Newtonsoft.Json.Linq.JObject(); jPrivateConfig.Add("storageAccountName", new Newtonsoft.Json.Linq.JValue(storageAccountName)); jPrivateConfig.Add("storageAccountKey", new Newtonsoft.Json.Linq.JValue(storageAccountKey)); jPrivateConfig.Add("storageAccountEndPoint", new Newtonsoft.Json.Linq.JValue(endpoint)); WriteVerbose("Installing WAD extension"); Version wadVersion = this._Helper.GetExtensionVersion(vm, vmStatus, OSType, AEMExtensionConstants.WADExtensionType[this.OSType], AEMExtensionConstants.WADExtensionPublisher[this.OSType]); VirtualMachineExtension vmExtParameters = new VirtualMachineExtension(); vmExtParameters.Publisher = AEMExtensionConstants.WADExtensionPublisher[this.OSType]; vmExtParameters.VirtualMachineExtensionType = AEMExtensionConstants.WADExtensionType[this.OSType]; vmExtParameters.TypeHandlerVersion = wadVersion.ToString(2); vmExtParameters.Settings = jPublicConfig; vmExtParameters.ProtectedSettings = jPrivateConfig; vmExtParameters.Location = vm.Location; vmExtParameters.AutoUpgradeMinorVersion = true; vmExtParameters.ForceUpdateTag = DateTime.Now.Ticks.ToString(); this.VirtualMachineExtensionClient.CreateOrUpdate(ResourceGroupName, vm.Name, extensionName, vmExtParameters); return(this.ComputeClient.ComputeManagementClient.VirtualMachines.Get(ResourceGroupName, vm.Name)); }
private void SetNewExtension(VirtualMachine selectedVM, VirtualMachineInstanceView selectedVMStatus) { // check VM identity // give VM idenity access to resources/resource groups // deploy extension on VM //TODO should we allow user assigned identity? if (selectedVM.Identity == null) { selectedVM.Identity = new VirtualMachineIdentity(type: ResourceIdentityType.SystemAssigned); selectedVM = this.ComputeClient.ComputeManagementClient.VirtualMachines. CreateOrUpdate(this.ResourceGroupName, this.VMName, selectedVM); } else if (selectedVM.Identity.Type == ResourceIdentityType.UserAssigned) { selectedVM.Identity.Type = ResourceIdentityType.SystemAssignedUserAssigned; selectedVM = this.ComputeClient.ComputeManagementClient.VirtualMachines. CreateOrUpdate(this.ResourceGroupName, this.VMName, selectedVM); } HashSet <string> scopes = new HashSet <string>(); int endIndex = 4; //Scope is set to resource group if (this.SetAccessToIndividualResources) { endIndex = 8; //Scope is set to resource } // Add VM Scope or Resource Group scope scopes.Add(String.Join("/", selectedVM.Id.Split('/').SubArray(0, endIndex))); //TODO: do we want to support unmanaged disks? scopes.Add(String.Join("/", selectedVM.StorageProfile.OsDisk.ManagedDisk.Id.Split('/').SubArray(0, endIndex))); foreach (var dataDisk in selectedVM.StorageProfile.DataDisks) { scopes.Add(String.Join("/", dataDisk.ManagedDisk.Id.Split('/').SubArray(0, endIndex))); } foreach (var nic in selectedVM.NetworkProfile.NetworkInterfaces) { scopes.Add(String.Join("/", nic.Id.Split('/').SubArray(0, endIndex))); } DateTime startTime = DateTime.Now; foreach (string scope in scopes) { /* In some cases, the role assignment cannot be created because the VM identity is not yet available for usage. */ bool created = false; while (!created) { string scopedRoleId = $"{scope}/providers/Microsoft.Authorization/roleDefinitions/{AEMExtensionConstants.NewExtensionRole}"; string roleDefinitionId = $"/subscriptions/{this.DefaultContext.Subscription.Id}/providers/Microsoft.Authorization/roleDefinitions/{AEMExtensionConstants.NewExtensionRole}"; var existingRoleAssignments = AuthClient.RoleAssignments.ListForScope(scope); var existingRoleAssignment = existingRoleAssignments.FirstOrDefault(assignmentTest => assignmentTest.Properties.PrincipalId.EqualsInsensitively(selectedVM.Identity.PrincipalId) && assignmentTest.Properties.RoleDefinitionId.EqualsInsensitively(roleDefinitionId) && assignmentTest.Properties.Scope.EqualsInsensitively(scope)); if (existingRoleAssignment != null) { this._Helper.WriteVerbose($"Role Assignment for scope {scope} already exists for principal {selectedVM.Identity.PrincipalId}"); created = true; break; } RoleAssignmentCreateParameters createParameters = new RoleAssignmentCreateParameters() { Properties = new RoleAssignmentProperties() { RoleDefinitionId = scopedRoleId, //TODO: do we want to support user assigned identity? PrincipalId = selectedVM.Identity.PrincipalId } }; try { string testMode = Environment.GetEnvironmentVariable("AZURE_TEST_MODE"); string assignmentName = Guid.NewGuid().ToString(); if ("Record".EqualsInsensitively(testMode) || Microsoft.WindowsAzure.Commands.Utilities.Common.TestMockSupport.RunningMocked) { // Make sure to use the same ID during test record and playback assignmentName = AEMHelper.GenerateGuid(scope); } AuthClient.RoleAssignments.Create(scope, assignmentName, createParameters); created = true; } catch (CloudException cex) { if (!("PrincipalNotFound".Equals(cex.Body.Code))) { throw; } this._Helper.WriteVerbose(cex.ToString()); } if (!created && (DateTime.Now - startTime).TotalSeconds < MAX_WAIT_TIME_FOR_SP_SECONDS) { this._Helper.WriteVerbose("Virtual Machine System Identity not available yet - waiting 5 seconds"); Microsoft.WindowsAzure.Commands.Utilities.Common.TestMockSupport.Delay(5000); } else if (!created) { this._Helper.WriteError($"Waited {MAX_WAIT_TIME_FOR_SP_SECONDS} seconds for VM identity to become available - giving up. Please try again later."); return; } } } var sapmonPublicConfig = new List <KeyValuePair>(); if (!String.IsNullOrEmpty(this.ProxyURI)) { sapmonPublicConfig.Add(new KeyValuePair() { Key = "proxy", Value = this.ProxyURI }); } if (this.DebugExtension.IsPresent) { sapmonPublicConfig.Add(new KeyValuePair() { Key = "debug", Value = "1" }); } ExtensionConfig jsonPublicConfig = new ExtensionConfig(); jsonPublicConfig.Config = sapmonPublicConfig; var vmExtensionConfig = new VirtualMachineExtension() { Publisher = AEMExtensionConstants.AEMExtensionPublisherv2[OSType], VirtualMachineExtensionType = AEMExtensionConstants.AEMExtensionTypev2[OSType], TypeHandlerVersion = AEMExtensionConstants.AEMExtensionVersionv2[OSType].ToString(2), Location = selectedVM.Location, Settings = jsonPublicConfig, AutoUpgradeMinorVersion = true, ForceUpdateTag = DateTime.Now.Ticks.ToString() }; if (NoWait.IsPresent) { var op = this.VirtualMachineExtensionClient.BeginCreateOrUpdateWithHttpMessagesAsync( this.ResourceGroupName, this.VMName, AEMExtensionConstants.AEMExtensionDefaultNamev2[OSType], vmExtensionConfig).GetAwaiter().GetResult(); var result = ComputeAutoMapperProfile.Mapper.Map <PSAzureOperationResponse>(op); WriteObject(result); } else { var op = this.VirtualMachineExtensionClient.CreateOrUpdateWithHttpMessagesAsync( this.ResourceGroupName, this.VMName, AEMExtensionConstants.AEMExtensionDefaultNamev2[OSType], vmExtensionConfig).GetAwaiter().GetResult(); var result = ComputeAutoMapperProfile.Mapper.Map <PSAzureOperationResponse>(op); WriteObject(result); } }
public override void ExecuteCmdlet() { this._StorageEndpoint = this.DefaultContext.Environment.GetEndpoint(AzureEnvironment.Endpoint.StorageEndpointSuffix); this._Helper = new AEMHelper((err) => this.WriteError(err), (msg) => this.WriteVerbose(msg), (msg) => this.WriteWarning(msg), this.CommandRuntime.Host.UI, AzureSession.Instance.ClientFactory.CreateArmClient <StorageManagementClient>( DefaultProfile.DefaultContext, AzureEnvironment.Endpoint.ResourceManager), this.DefaultContext.Subscription, this._StorageEndpoint); base.ExecuteCmdlet(); ExecuteClientAction(() => { this._Helper.WriteVerbose("Retrieving VM..."); var selectedVM = ComputeClient.ComputeManagementClient.VirtualMachines.Get(this.ResourceGroupName, this.VMName); var selectedVMStatus = ComputeClient.ComputeManagementClient.VirtualMachines.GetWithInstanceView(this.ResourceGroupName, this.VMName).Body.InstanceView; if (selectedVM == null) { var subscriptionId = this.DefaultContext.Subscription.Id; this._Helper.WriteError("No virtual machine with name {0} in resource group {1} in subscription {2} found", this.VMName, this.ResourceGroupName, subscriptionId); return; } var osdisk = selectedVM.StorageProfile.OsDisk; if (String.IsNullOrEmpty(this.OSType)) { this.OSType = osdisk.OsType.ToString(); } if (String.IsNullOrEmpty(this.OSType)) { this._Helper.WriteError("Could not determine Operating System of the VM. Please provide the Operating System type ({0} or {1}) via parameter OSType", AEMExtensionConstants.OSTypeWindows, AEMExtensionConstants.OSTypeLinux); return; } var aemExtension = AEMHelper.GetAEMExtension(selectedVM, this.OSType); /* * no extension + new extension switch => install new extension * new extension + new extension switch => install new extension * new extension + no extension switch => install new extension * no extension + no new extension switch => install old extension * old extension + no new extension switch => install old extension * old extension + new extension switch => error */ if ((aemExtension == null && InstallNewExtension.IsPresent) || (AEMHelper.IsNewExtension(aemExtension, this.OSType))) { this.SetNewExtension(selectedVM, selectedVMStatus); } else if ((aemExtension == null && !InstallNewExtension.IsPresent) || (AEMHelper.IsOldExtension(aemExtension, this.OSType) && !InstallNewExtension.IsPresent)) { this.SetOldExtension(selectedVM, selectedVMStatus); } else { this._Helper.WriteVerbose($"Migration from the old extension to the new one is not supported. " + $"Please remove the old extension first. (" + $"Extension installed={aemExtension != null} " + $"IsNewExtension={AEMHelper.IsNewExtension(aemExtension, this.OSType)} " + $"IsOldExtension={AEMHelper.IsOldExtension(aemExtension, this.OSType)}" + $"InstallNewExtension={InstallNewExtension.IsPresent}"); this._Helper.WriteError("Migration from the old extension to the new one is not supported. Please remove the old extension first."); return; } }); }
private List <AEMTestResult> TestOldExtension(VirtualMachine selectedVM, VirtualMachineInstanceView selectedVMStatus, VirtualMachineExtension monExtension) { var osdisk = selectedVM.StorageProfile.OsDisk; List <AEMTestResult> partialResults = new List <AEMTestResult>(); this._Helper.WriteHost("Azure Enhanced Monitoring Extension for SAP Installation check...", false); string monPublicConfig = null; if (monExtension != null) { monPublicConfig = monExtension.Settings.ToString(); } if (monExtension == null || String.IsNullOrEmpty(monPublicConfig)) { partialResults.Add(new AEMTestResult("Azure Enhanced Monitoring Extension for SAP Installation check", false)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } else { partialResults.Add(new AEMTestResult("Azure Enhanced Monitoring Extension for SAP Installation check", true)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } //################################################# //################################################# var accounts = new List <string>(); //var osdisk = selectedVM.StorageProfile.OsDisk; var osaccountName = String.Empty; if (osdisk.ManagedDisk == null) { var accountName = this._Helper.GetStorageAccountFromUri(osdisk.Vhd.Uri); osaccountName = accountName; accounts.Add(accountName); } var dataDisks = selectedVM.StorageProfile.DataDisks; foreach (var disk in dataDisks) { if (disk.ManagedDisk != null) { continue; } var accountName = this._Helper.GetStorageAccountFromUri(disk.Vhd.Uri); if (!accounts.Contains(accountName)) { accounts.Add(accountName); } } //################################################# //# Check storage metrics //################################################# this._Helper.WriteHost("Storage Metrics check..."); var metricsResult = new AEMTestResult("Storage Metrics check"); partialResults.Add(metricsResult); if (!this.SkipStorageCheck.IsPresent) { foreach (var account in accounts) { var accountResult = new AEMTestResult("Storage Metrics check for {0}", account); metricsResult.PartialResults.Add(accountResult); this._Helper.WriteHost("\tStorage Metrics check for {0}...", account); var storage = this._Helper.GetStorageAccountFromCache(account); if (!this._Helper.IsPremiumStorageAccount(storage)) { this._Helper.WriteHost("\t\tStorage Metrics configuration check for {0}...", false, account); var currentConfig = this._Helper.GetStorageAnalytics(account); bool storageConfigOk = false; if (!this._Helper.CheckStorageAnalytics(account, currentConfig)) { accountResult.PartialResults.Add(new AEMTestResult("Storage Metrics configuration check for {0}", false, account)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } else { accountResult.PartialResults.Add(new AEMTestResult("Storage Metrics configuration check for {0}", true, account)); this._Helper.WriteHost("OK ", ConsoleColor.Green); storageConfigOk = true; } this._Helper.WriteHost("\t\tStorage Metrics data check for {0}...", false, account); var filterMinute = Microsoft.WindowsAzure.Storage.Table.TableQuery. GenerateFilterConditionForDate("Timestamp", "gt", DateTime.Now.AddMinutes(AEMExtensionConstants.ContentAgeInMinutes * -1)); if (storageConfigOk && this._Helper.CheckTableAndContent(account, "$MetricsMinutePrimaryTransactionsBlob", filterMinute, ".", false, this.WaitTimeInMinutes)) { this._Helper.WriteHost("OK ", ConsoleColor.Green); accountResult.PartialResults.Add(new AEMTestResult("Storage Metrics data check for {0}", true, account)); } else { accountResult.PartialResults.Add(new AEMTestResult("Storage Metrics data check for {0}", false, account)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } } else { accountResult.PartialResults.Add(new AEMTestResult("Storage Metrics not available for Premium Storage account {0}", true, account)); this._Helper.WriteHost("\t\tStorage Metrics not available for Premium Storage account {0}...", false, account); this._Helper.WriteHost("OK ", ConsoleColor.Green); } } if (accounts.Count == 0) { metricsResult.Result = true; } } else { metricsResult.Result = true; this._Helper.WriteHost("Skipped ", ConsoleColor.Yellow); } //################################################# //################################################# //################################################# //# Check Azure Enhanced Monitoring Extension for SAP Configuration //################################################# this._Helper.WriteHost("Azure Enhanced Monitoring Extension for SAP public configuration check...", false); var aemConfigResult = new AEMTestResult("Azure Enhanced Monitoring Extension for SAP public configuration check"); partialResults.Add(aemConfigResult); JObject sapmonPublicConfig = null; if (monExtension != null) { this._Helper.WriteHost(""); //New Line sapmonPublicConfig = JsonConvert.DeserializeObject(monPublicConfig) as JObject; StorageAccount storage = null; var osaccountIsPremium = false; if (!String.IsNullOrEmpty(osaccountName)) { storage = this._Helper.GetStorageAccountFromCache(osaccountName); osaccountIsPremium = this._Helper.IsPremiumStorageAccount(osaccountName); } var vmSize = selectedVM.HardwareProfile.VmSize; this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Size", "vmsize", sapmonPublicConfig, vmSize.ToString(), aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Memory", "vm.memory.isovercommitted", sapmonPublicConfig, 0, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM CPU", "vm.cpu.isovercommitted", sapmonPublicConfig, 0, aemConfigResult); this._Helper.MonitoringPropertyExists("Azure Enhanced Monitoring Extension for SAP public configuration check: Script Version", "script.version", sapmonPublicConfig, aemConfigResult); var vmSLA = this._Helper.GetVMSLA(selectedVM); if (vmSLA.HasSLA) { this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM SLA IOPS", "vm.sla.iops", sapmonPublicConfig, vmSLA.IOPS, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM SLA Throughput", "vm.sla.throughput", sapmonPublicConfig, vmSLA.TP, aemConfigResult); } int wadEnabled; if (this._Helper.GetMonPropertyValue("wad.isenabled", sapmonPublicConfig, out wadEnabled)) { if (wadEnabled == 1) { this._Helper.MonitoringPropertyExists("Azure Enhanced Monitoring Extension for SAP public configuration check: WAD name", "wad.name", sapmonPublicConfig, aemConfigResult); this._Helper.MonitoringPropertyExists("Azure Enhanced Monitoring Extension for SAP public configuration check: WAD URI", "wad.uri", sapmonPublicConfig, aemConfigResult); } else { this._Helper.MonitoringPropertyExists("Azure Enhanced Monitoring Extension for SAP public configuration check: WAD name", "wad.name", sapmonPublicConfig, aemConfigResult, false); this._Helper.MonitoringPropertyExists("Azure Enhanced Monitoring Extension for SAP public configuration check: WAD URI", "wad.uri", sapmonPublicConfig, aemConfigResult, false); } } else { string message = "Azure Enhanced Monitoring Extension for SAP public configuration check:"; aemConfigResult.PartialResults.Add(new AEMTestResult(message, false)); this._Helper.WriteHost(message + "...", false); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } if (!osaccountIsPremium && storage != null) { var endpoint = this._Helper.GetAzureSAPTableEndpoint(storage); var minuteUri = endpoint + "$MetricsMinutePrimaryTransactionsBlob"; this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS disk URI Key", "osdisk.connminute", sapmonPublicConfig, osaccountName + ".minute", aemConfigResult); //# TODO: check uri config this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS disk URI Value", osaccountName + ".minute.uri", sapmonPublicConfig, minuteUri, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS disk URI Name", osaccountName + ".minute.name", sapmonPublicConfig, osaccountName, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS Disk Type", "osdisk.type", sapmonPublicConfig, AEMExtensionConstants.DISK_TYPE_STANDARD, aemConfigResult); } else if (storage != null) { var sla = this._Helper.GetDiskSLA(osdisk); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS Disk Type", "osdisk.type", sapmonPublicConfig, AEMExtensionConstants.DISK_TYPE_PREMIUM, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS Disk SLA IOPS", "osdisk.sla.throughput", sapmonPublicConfig, sla.TP, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS Disk SLA Throughput", "osdisk.sla.iops", sapmonPublicConfig, sla.IOPS, aemConfigResult); } else { var resId = new ResourceIdentifier(osdisk.ManagedDisk.Id); var osDiskMD = ComputeClient.ComputeManagementClient.Disks.Get(resId.ResourceGroupName, resId.ResourceName); if (osDiskMD.Sku.Name == StorageAccountTypes.PremiumLRS) { var sla = this._Helper.GetDiskSLA(osDiskMD.DiskSizeGB, null); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS Disk Type", "osdisk.type", sapmonPublicConfig, AEMExtensionConstants.DISK_TYPE_PREMIUM_MD, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS Disk SLA IOPS", "osdisk.sla.throughput", sapmonPublicConfig, sla.TP, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS Disk SLA Throughput", "osdisk.sla.iops", sapmonPublicConfig, sla.IOPS, aemConfigResult); } else { this._Helper.WriteWarning("[WARN] Standard Managed Disks are not supported."); } } if (osdisk.ManagedDisk == null) { this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM OS disk name", "osdisk.name", sapmonPublicConfig, this._Helper.GetDiskName(osdisk.Vhd.Uri), aemConfigResult); } var diskNumber = 1; foreach (var disk in dataDisks) { if (disk.ManagedDisk != null) { var resId = new ResourceIdentifier(disk.ManagedDisk.Id); var diskMD = ComputeClient.ComputeManagementClient.Disks.Get(resId.ResourceGroupName, resId.ResourceName); if (diskMD.Sku.Name == StorageAccountTypes.PremiumLRS) { var sla = this._Helper.GetDiskSLA(diskMD.DiskSizeGB, null); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " Type", "disk.type." + diskNumber, sapmonPublicConfig, AEMExtensionConstants.DISK_TYPE_PREMIUM_MD, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " SLA IOPS", "disk.sla.throughput." + diskNumber, sapmonPublicConfig, sla.TP, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " SLA Throughput", "disk.sla.iops." + diskNumber, sapmonPublicConfig, sla.IOPS, aemConfigResult); } else if (diskMD.Sku.Name == StorageAccountTypes.UltraSSDLRS) { this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " Type", "disk.type." + diskNumber, sapmonPublicConfig, AEMExtensionConstants.DISK_TYPE_PREMIUM_MD, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " SLA IOPS", "disk.sla.throughput." + diskNumber, sapmonPublicConfig, diskMD.DiskMBpsReadWrite, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " SLA Throughput", "disk.sla.iops." + diskNumber, sapmonPublicConfig, diskMD.DiskIOPSReadWrite, aemConfigResult); } else { this._Helper.WriteWarning("[WARN] Standard Managed Disks are not supported."); } } else { var accountName = this._Helper.GetStorageAccountFromUri(disk.Vhd.Uri); storage = this._Helper.GetStorageAccountFromCache(accountName); var accountIsPremium = this._Helper.IsPremiumStorageAccount(storage); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " LUN", "disk.lun." + diskNumber, sapmonPublicConfig, disk.Lun, aemConfigResult); if (!accountIsPremium) { var endpoint = this._Helper.GetAzureSAPTableEndpoint(storage); var minuteUri = endpoint + "$MetricsMinutePrimaryTransactionsBlob"; this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " URI Key", "disk.connminute." + diskNumber, sapmonPublicConfig, accountName + ".minute", aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " URI Value", accountName + ".minute.uri", sapmonPublicConfig, minuteUri, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " URI Name", accountName + ".minute.name", sapmonPublicConfig, accountName, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " Type", "disk.type." + diskNumber, sapmonPublicConfig, AEMExtensionConstants.DISK_TYPE_STANDARD, aemConfigResult); } else { var sla = this._Helper.GetDiskSLA(disk); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " Type", "disk.type." + diskNumber, sapmonPublicConfig, AEMExtensionConstants.DISK_TYPE_PREMIUM, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " SLA IOPS", "disk.sla.throughput." + diskNumber, sapmonPublicConfig, sla.TP, aemConfigResult); this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " SLA Throughput", "disk.sla.iops." + diskNumber, sapmonPublicConfig, sla.IOPS, aemConfigResult); } this._Helper.CheckMonitoringProperty("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disk " + diskNumber + " name", "disk.name." + diskNumber, sapmonPublicConfig, this._Helper.GetDiskName(disk.Vhd.Uri), aemConfigResult); } diskNumber += 1; } if (dataDisks.Count == 0) { aemConfigResult.PartialResults.Add(new AEMTestResult("Azure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disks", true)); this._Helper.WriteHost("\tAzure Enhanced Monitoring Extension for SAP public configuration check: VM Data Disks ", false); this._Helper.WriteHost("OK ", ConsoleColor.Green); } } else { aemConfigResult.Result = false; this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } //################################################# //################################################# //################################################# //# Check WAD Configuration //################################################# int iswadEnabled; if (this._Helper.GetMonPropertyValue("wad.isenabled", sapmonPublicConfig, out iswadEnabled) && iswadEnabled == 1) { var wadConfigResult = new AEMTestResult("IaaSDiagnostics check"); partialResults.Add(wadConfigResult); string wadPublicConfig = null; var wadExtension = AEMHelper.GetWADExtension(selectedVM, this.OSType); if (wadExtension != null) { wadPublicConfig = wadExtension.Settings.ToString(); } this._Helper.WriteHost("IaaSDiagnostics check...", false); if (wadExtension != null) { this._Helper.WriteHost(""); //New Line this._Helper.WriteHost("\tIaaSDiagnostics configuration check...", false); var currentJSONConfig = JsonConvert.DeserializeObject(wadPublicConfig) as Newtonsoft.Json.Linq.JObject; var base64 = currentJSONConfig["xmlCfg"] as Newtonsoft.Json.Linq.JValue; System.Xml.XmlDocument currentConfig = new System.Xml.XmlDocument(); currentConfig.LoadXml(Encoding.UTF8.GetString(System.Convert.FromBase64String(base64.Value.ToString()))); if (!this._Helper.CheckWADConfiguration(currentConfig)) { wadConfigResult.PartialResults.Add(new AEMTestResult("IaaSDiagnostics configuration check", false)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } else { wadConfigResult.PartialResults.Add(new AEMTestResult("IaaSDiagnostics configuration check", true)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } this._Helper.WriteHost("\tIaaSDiagnostics performance counters check..."); var wadPerfCountersResult = new AEMTestResult("IaaSDiagnostics performance counters check"); wadConfigResult.PartialResults.Add(wadPerfCountersResult); foreach (var perfCounter in AEMExtensionConstants.PerformanceCounters[this.OSType]) { this._Helper.WriteHost("\t\tIaaSDiagnostics performance counters " + (perfCounter.counterSpecifier) + "check...", false); var currentCounter = currentConfig.SelectSingleNode("/WadCfg/DiagnosticMonitorConfiguration/PerformanceCounters/PerformanceCounterConfiguration[@counterSpecifier = '" + perfCounter.counterSpecifier + "']"); if (currentCounter != null) { wadPerfCountersResult.PartialResults.Add(new AEMTestResult("IaaSDiagnostics performance counters " + (perfCounter.counterSpecifier) + "check...", true)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } else { wadPerfCountersResult.PartialResults.Add(new AEMTestResult("IaaSDiagnostics performance counters " + (perfCounter.counterSpecifier) + "check...", false)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } } string wadstorage; if (!this._Helper.GetMonPropertyValue <string>("wad.name", sapmonPublicConfig, out wadstorage)) { wadstorage = null; } this._Helper.WriteHost("\tIaaSDiagnostics data check...", false); var deploymentId = String.Empty; var roleName = String.Empty; var extStatuses = AEMHelper.GetAEMExtensionStatus(selectedVM, selectedVMStatus, this.OSType); InstanceViewStatus aemStatus = null; if (extStatuses != null && extStatuses.Statuses != null) { aemStatus = extStatuses.Statuses.FirstOrDefault(stat => Regex.Match(stat.Message, "deploymentId=(\\S*) roleInstance=(\\S*)").Success); } if (aemStatus != null) { var match = Regex.Match(aemStatus.Message, "deploymentId=(\\S*) roleInstance=(\\S*)"); deploymentId = match.Groups[1].Value; roleName = match.Groups[2].Value; } else { this._Helper.WriteWarning("DeploymentId and RoleInstanceName could not be parsed from extension status"); } var ok = false; if (!this.SkipStorageCheck.IsPresent && (!String.IsNullOrEmpty(deploymentId)) && (!String.IsNullOrEmpty(roleName)) && (!String.IsNullOrEmpty(wadstorage))) { if (this.OSType.Equals(AEMExtensionConstants.OSTypeLinux, StringComparison.InvariantCultureIgnoreCase)) { ok = this._Helper.CheckDiagnosticsTable(wadstorage, deploymentId, selectedVM.OsProfile.ComputerName, ".", this.OSType, this.WaitTimeInMinutes); } else { string filterMinute = "Role eq '" + AEMExtensionConstants.ROLECONTENT + "' and DeploymentId eq '" + deploymentId + "' and RoleInstance eq '" + roleName + "' and PartitionKey gt '0" + DateTime.UtcNow.AddMinutes(AEMExtensionConstants.ContentAgeInMinutes * -1).Ticks + "'"; ok = this._Helper.CheckTableAndContent(wadstorage, AEMExtensionConstants.WadTableName, filterMinute, ".", false, this.WaitTimeInMinutes); } } if (ok && !this.SkipStorageCheck.IsPresent) { wadConfigResult.PartialResults.Add(new AEMTestResult("IaaSDiagnostics data check", true)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } else if (!this.SkipStorageCheck.IsPresent) { wadConfigResult.PartialResults.Add(new AEMTestResult("IaaSDiagnostics data check", false)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } else { this._Helper.WriteHost("Skipped ", ConsoleColor.Yellow); } } else { wadConfigResult.Result = false; this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } } return(partialResults); }
private List <AEMTestResult> TestNewExtension(VirtualMachine selectedVM, VirtualMachineInstanceView selectedVMStatus, VirtualMachineExtension monExtension) { List <AEMTestResult> partialResults = new List <AEMTestResult>(); this._Helper.WriteHost("Azure Extension for SAP Installation check...", false); if (!AEMHelper.IsNewExtension(monExtension, this.OSType)) { partialResults.Add(new AEMTestResult("Azure Extension for SAP Installation check", false)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } else { partialResults.Add(new AEMTestResult("Azure Extension for SAP Installation check", true)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } this._Helper.WriteHost("VM Identity Check...", false); if (selectedVM.Identity == null || selectedVM.Identity.Type == ResourceIdentityType.UserAssigned) { partialResults.Add(new AEMTestResult("VM Identity Check", false)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } else { partialResults.Add(new AEMTestResult("VM Identity Check", true)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } var permissionResult = new AEMTestResult("Permission Check"); partialResults.Add(permissionResult); this._Helper.WriteHost("Permission Check...", true); List <string> resourceIds = new List <string>(); int endIndexShort = 4; //Scope is set to resource group int endIndexLong = 8; //Scope is set to resource // Add VM Scope or Resource Group scope resourceIds.Add(selectedVM.Id); //TODO: do we want to support unmanaged disks? resourceIds.Add(selectedVM.StorageProfile.OsDisk.ManagedDisk.Id); foreach (var dataDisk in selectedVM.StorageProfile.DataDisks) { resourceIds.Add(dataDisk.ManagedDisk.Id); } foreach (var nic in selectedVM.NetworkProfile.NetworkInterfaces) { resourceIds.Add(nic.Id); } /* * Individual resources could be located in different resource groups. * We therefore have to check both the resource group scope and the resource scope for every resource */ HashSet <string> testedScopeOK = new HashSet <string>(); HashSet <string> testedScopeNOK = new HashSet <string>(); foreach (string resourceId in resourceIds) { string scopeResourceGroup = String.Join("/", resourceId.Split('/').SubArray(0, endIndexShort)); string scopeResource = String.Join("/", resourceId.Split('/').SubArray(0, endIndexLong)); string scopedRoleIdResourceGroup = $"{scopeResourceGroup}/providers/Microsoft.Authorization/roleDefinitions/{AEMExtensionConstants.NewExtensionRole}"; string scopedRoleIdResource = $"{scopeResource}/providers/Microsoft.Authorization/roleDefinitions/{AEMExtensionConstants.NewExtensionRole}"; string roleDefinitionId = $"/subscriptions/{this.DefaultContext.Subscription.Id}/providers/Microsoft.Authorization/roleDefinitions/{AEMExtensionConstants.NewExtensionRole}"; this._Helper.WriteHost("\tPermission Check for Resource {0}...", false, resourceId); bool checkOk = false; bool?groupOK = null; if (testedScopeOK.Contains(scopeResourceGroup)) { groupOK = true; } if (testedScopeNOK.Contains(scopeResourceGroup)) { groupOK = false; } bool?resourceOk = null; if (testedScopeOK.Contains(scopeResource)) { resourceOk = true; } if (testedScopeNOK.Contains(scopeResource)) { resourceOk = false; } checkOk = AEMHelper.CheckScopePermissions(groupOK, resourceOk, scopeResourceGroup, scopeResource, roleDefinitionId, selectedVM, testedScopeOK, testedScopeNOK, this.TestScope); if (checkOk) { permissionResult.PartialResults.Add(new AEMTestResult("Permission Check for Resource {0}", true, resourceId)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } else { permissionResult.PartialResults.Add(new AEMTestResult("Permission Check for Resource {0}", false, resourceId)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); } } return(partialResults); }
public override void ExecuteCmdlet() { this._Helper = new AEMHelper((err) => this.WriteError(err), (msg) => this.WriteVerbose(msg), (msg) => this.WriteWarning(msg), this.CommandRuntime.Host.UI, AzureSession.Instance.ClientFactory.CreateArmClient <StorageManagementClient>(DefaultProfile.DefaultContext, AzureEnvironment.Endpoint.ResourceManager), this.DefaultContext.Subscription, this.DefaultContext.Environment.GetEndpoint(AzureEnvironment.Endpoint.StorageEndpointSuffix)); this._Helper.WriteVerbose("Starting TestAzureRmVMAEMExtension"); base.ExecuteCmdlet(); ExecuteClientAction(() => { AEMTestResult rootResult = new AEMTestResult(); rootResult.TestName = "Azure Enhanced Monitoring Test"; //################################################# //# Check if VM exists //################################################# this._Helper.WriteHost("VM Existence check for {0} ...", false, this.VMName); var selectedVM = this.ComputeClient.ComputeManagementClient.VirtualMachines.Get(this.ResourceGroupName, this.VMName); var selectedVMStatus = this.ComputeClient.ComputeManagementClient.VirtualMachines.GetWithInstanceView(this.ResourceGroupName, this.VMName).Body.InstanceView; if (selectedVM == null) { rootResult.PartialResults.Add(new AEMTestResult("VM Existence check for {0}", false, this.VMName)); this._Helper.WriteHost("NOT OK ", ConsoleColor.Red); return; } else { rootResult.PartialResults.Add(new AEMTestResult("VM Existence check for {0}", true, this.VMName)); this._Helper.WriteHost("OK ", ConsoleColor.Green); } //################################################# //################################################# var osdisk = selectedVM.StorageProfile.OsDisk; if (String.IsNullOrEmpty(this.OSType)) { this.OSType = osdisk.OsType.ToString(); } if (String.IsNullOrEmpty(this.OSType)) { this._Helper.WriteError("Could not determine Operating System of the VM. Please provide the Operating System type ({0} or {1}) via parameter OSType", AEMExtensionConstants.OSTypeWindows, AEMExtensionConstants.OSTypeLinux); return; } //################################################# //# Check for Azure Enhanced Monitoring Extension for SAP //################################################# var monExtension = AEMHelper.GetAEMExtension(selectedVM, this.OSType); if (AEMHelper.IsNewExtension(monExtension, this.OSType)) { var newResults = this.TestNewExtension(selectedVM, selectedVMStatus, monExtension); rootResult.PartialResults.AddRange(newResults); } else { var oldResults = this.TestOldExtension(selectedVM, selectedVMStatus, monExtension); rootResult.PartialResults.AddRange(oldResults); } if (!rootResult.Result) { this._Helper.WriteHost("The script found some configuration issues. Please run the Set-AzVMAEMExtension commandlet to update the configuration of the virtual machine!"); } this._Helper.WriteVerbose("TestAzureRmVMAEMExtension Done (" + rootResult.Result + ")"); var result = ComputeAutoMapperProfile.Mapper.Map <AEMTestResult>(rootResult); WriteObject(result); }); }