Um einen schnellen Überblick über relevante Kennzahlen in einer VMware vCloud Director Infrastruktur zu erhalten, gibt das Produkt leider nicht so viele Information an einer zentralen Stelle her wie ich mir das wüschen würde. Zur internen Verwendung, habe ich mir daher einen Ressource Usage Report mit VMware PowerCLI erstellt.
Für die Erfassung der Daten nutze ich das vCloud Director und das vRealize Operations Manager PowerShell Modul von VMware PowerCLI. Die Verwendung der vRealize Operations Manager Daten in meinem Report ist momentan eine Spielerei um zu evaluieren, ob man das eventuell weiter ausbauen kann und damit auf Daten direkt aus dem vCloud Director komplett verzichten könnte. Bisher habe ich aber noch keine Lösung für die benötigten Edge Gateay Informationen gefunden.
Zur Darstellung des Reports habe ich mich primär für eine HTML Seite entschieden. Diese habe ich mit Hilfe des PowerShell Moduls aus dem Artikel PowerShell: Daten als HTML Report ausgeben auch ganz übersichtlich hinbekommen. Alternativ kann der Export aber auch als CSV erfolgen, was die Weiterverarbeitung der Daten natürlich erleichtern soll.
Ressource Usage Report im Detail
Folgende Werte habe ich in der ersten Version des Reports zusammengeführt:
Org | Name der Organisation |
OrgVdc | Name des VDC |
OmHealth | VDC Health Badge aus dem vROps |
CpuUsed | Aktuelle CPU Nutzung |
RamUsed | Aktuelle RAM Nutzung |
VApps | Anzahl der vApps |
VAppTemplates | Anzahl der vApp Templates |
VMs | Anzahl der VMs |
VMsOff | Anzahl ausgeschalteter VMs |
StorageProfile | Liste der Storage Profil |
StorageLimit | Zugewiesener Storage pro Profil |
StorageUsed | Genutzter Storage |
EdgeGateway | Name des Edge Gateway in angegebenen Netz |
Ip | IP des Edge Gateway |
IpRangeCount | Anzahl zusätzliche IP`s des Edge Gateway |
Edge Gateway Daten
Hinter der Ausgabe der Edge Gateway Daten steht der Gedanke, dass es ein bestimmtes externes Netz gibt, welches besonders erfasst werden muss. Zum Beispiel weil in diesem Netz öffentliche Adressen vergeben werden.
Daher kann dem Cmdlet mit dem Parameter -NetworkName diese Netz mitgegeben werden. Mit Hilfe einer etwas abgewandelten Funktion aus meinem Artikel vCloud Director Edge-Gateway IP Report werden die IP`s und der Name des Edge Gateway in diesem Netz für den Report erfasst.
Theoretisch ist diese Funktion auch unabhängig von dem Report nutzbar:
$EdgeView = Search-Cloud -QueryType EdgeGateway | Get-CIView Get-EdgeReport -EdgeView $EdgeView | Format-Table -Autosize
Aufruf Ressource Usage Report
Um das Modul zu verwenden müssen ein paar vorbereitende Schritte durchgeführt werden:
- VMware PowerCLI Module Importieren (Download – Version 6.5.1)
- VMware-vCD-Report Modul Importieren (Download – Version 1.0)
- VMware vCloud Director verbinden (Connect-CIServer)
- (optional) VMware vRealize Operations Manager verbinden (Connect-OMServer)
# Import VMware Modules Get-Module -ListAvailable -Name VMware* | Import-Module # Import my VMware-vCD-Report Module Import-Module ".\VMware-vCD-Report\PEC-vCD-Report.psm1" # Connect vCD Connect-CIServer <Your Server> # Connect vROps Connect-OMServer <Your Server>
Der Report kann nun mit der Funktion Get-vCDReport als HTML erzeugt werden:
Get-vCDReport -NetworkName "MyExternalNetwork" -OutputFilePath "C:\Temp\" -OMMetrics:$True -OutputType "HTML"
Soll die Ausgabe als CSV erfolgen:
Get-vCDReport -NetworkName "MyExternalNetwork" -OutputFilePath "C:\Temp\" -OMMetrics:$True -OutputType "CSV"
Falls keine VMware vRealize Operations Manager Daten gesammelt werden sollen:
Get-vCDReport -NetworkName "MyExternalNetwork" -OutputFilePath "C:\Temp\" -OMMetrics:$False
Ressource Usage Report Code
Ich beschränke mich hier auf die beiden exportierten Funktionen des PowerShell Moduls. Zusätzlich habe ich mich aber zweier anderer Funktionen aus der Community bedient:
-
Get-IPrange
Das komplette Modul aus dem Beitrag ist meinem GitHub Repository VMware-vCD-Report zu finden.
Get-vCDReport
Die Haupt-Funktion des Moduls.
Function Get-vCDReport{ <# .SYNOPSIS Creates the HTML or CSV Output of VMware vCloud Director Ressources. .EXAMPLE Get-vCDReport -NetworkName "MyExternalNetwork" -OutputFilePath "C:\Temp\" -OMMetrics:$True -OutputType "HTML" #> Param ( [Parameter(Mandatory=$False, ValueFromPipeline=$False)] [ValidateNotNullorEmpty()] [String]$NetworkName = "NONE", [Parameter(Mandatory=$False, ValueFromPipeline=$False)] [ValidateNotNullorEmpty()] [String]$OutputFilePath = ".\", [Parameter(Mandatory=$False, ValueFromPipeline=$False)] [ValidateNotNullorEmpty()] [Switch]$OMMetrics = $true, [Parameter(Mandatory=$False, ValueFromPipeline=$False)] [ValidateNotNullorEmpty()] [ValidateSet("CSV","HTML")] [String]$OutputType = "HTML" ) $OrgViews = Search-Cloud -QueryType Organization | Get-CIView -Verbose:$false if ($OMMetrics) { $OmHealthStati = Get-OMResource -ResourceKind ORG_VDC } $Report = @() foreach ($OrgView in $OrgViews) { foreach ($OrgVdc in $OrgView.Vdcs.Vdc){ $obj = "" | Select-Object Org, OrgVdc, OmHealth, "CpuUsed(GHz)", "RamUsed(GB)", VApps, VAppTemplates, VMs, VMsOff, ` StorageProfiles, "StorageLimit(GB)", "StorageUsed(GB)", EdgeGateway, Ip, IpRangeCount $obj.Org = $OrgView.Name $obj.OrgVdc = $OrgVdc.Name if ($OMMetrics) { try { $obj.OmHealth = ($OmHealthStati | Where-Object {$_.Name -eq $OrgVdc.Name} ).Health } catch { $obj.OrgVdc = "N/A" } } else { $obj.OrgVdc = "N/A" } $OrgVdc = Search-Cloud -QueryType AdminOrgVdc -Name $OrgVdc.Name $OrgVdcView = $OrgVdc | Get-CIView -Verbose:$false #$obj."CpuAllocated(GHz)" = [Math]::Round(($OrgVdcView.ComputeCapacity.Cpu.Allocated / 1000), 2) $obj."CpuUsed(GHz)" = [Math]::Round(($OrgVdcView.ComputeCapacity.Cpu.Used / 1000), 2) #$obj."RamAllocated(GB)" = [Math]::Round(($OrgVdcView.ComputeCapacity.Memory.Allocated / 1024), 2) $obj."RamUsed(GB)" = [Math]::Round(($OrgVdcView.ComputeCapacity.Memory.Used / 1024), 2) $obj.VApps = $OrgVdc.NumberOfVApps $obj.VAppTemplates = $OrgVdc.NumberOfVAppTemplates [Array]$OrgVdcVMs = Search-Cloud -QueryType AdminVM -Filter "Vdc==$($OrgVDC.Id)" if ($OrgVdcVMs) { $obj.VMs = $OrgVdcVMs.Count [Array]$OrgVdcVMsOff = $OrgVdcVMs | where {$_.Status -eq "POWERED_OFF"} if ($OrgVdcVMsOff) { $obj.VMsOff = $OrgVdcVMsOff.Count } else { $obj.VMsOff = 0 } } else{ $obj.VMs = 0 $obj.VMsOff = 0 } [Array]$OrgVdcStorageView = Search-Cloud -QueryType AdminOrgVdcStorageProfile -Filter "VdcName==$($OrgVdc.Name)" $obj.StorageProfiles = $OrgVdcStorageView.Name -join ", " $StorageLimit = @() foreach ($StorageObject in $OrgVdcStorageView.StorageLimitMB) { $StorageLimit += [Math]::Round(($StorageObject / 1024), 2) } $obj."StorageLimit(GB)" = $StorageLimit -join ", " $StorageUsed = @() foreach ($StorageObject in $OrgVdcStorageView.StorageUsedMB) { $StorageUsed += [Math]::Round(($StorageObject / 1024), 2) } $obj."StorageUsed(GB)" = $StorageUsed -join ", " $EdgeView = Search-Cloud -QueryType EdgeGateway -Filter "Vdc==$($OrgVdcView.Id)" | Get-CIView if ($EdgeView) { $VcdEdgeReport = Get-EdgeReport -EdgeView $EdgeView | Where-Object {$_.NetworkName -like $NetworkName} if ($VcdEdgeReport) { $obj.EdgeGateway = $VcdEdgeReport.EdgeName $obj.Ip = $VcdEdgeReport.IP $obj.IpRangeCount = $VcdEdgeReport.IPRangeCount } } $Report += $obj } } if ($OutputType -eq "HTML") { $OutputFileName = $OutputFilePath + "HtmlReport.html" $InputObject = @{Object = $Report} $trash = Export-HtmlReport -InputObject $InputObject -ReportTitle "vCD Ressource Usage Report" -OutputFileName $OutputFileName } elseif ($OutputType -eq "CSV") { $OutputFileName = $OutputFilePath + "CsvReport.csv" $Report | Export-Csv -Path $OutputFileName -Delimiter ";" } "Output File: '$OutputFileName'`n" }
Get-EdgeReport
Eigentlich nur eine Sub-Funktion aber so nützlich, dass ich die doch exportiert habe.
Function Get-EdgeReport{ <# .SYNOPSIS Creates a Report of Edge Gateway Details. .EXAMPLE $EdgeView = Search-Cloud -QueryType EdgeGateway | Get-CIView Get-EdgeReport -EdgeView $EdgeView | Format-Table -Autosize #> Param ( [Parameter(Mandatory=$True, ValueFromPipeline=$False)] [ValidateNotNullorEmpty()] $EdgeView ) $EdgeReport = @() foreach ($Edge in $EdgeView) { [Array]$GatewayInterfaces = $Edge.Configuration.GatewayInterfaces foreach($GatewayInterface in $GatewayInterfaces.GatewayInterface){ $obj = "" | Select-Object EdgeName, NetworkName, IP, IPRangeCount $obj.EdgeName = $Edge.Name $obj.NetworkName = $GatewayInterface.Name $obj.IP = $GatewayInterface.SubnetParticipation.IpAddress [Array] $RangeReport = @() if ($GatewayInterface.SubnetParticipation.IpRanges){ foreach ($IPRange in $GatewayInterface.SubnetParticipation.IpRanges.IpRange) { [Array] $Range = Get-IPrange -start $IPRange.StartAddress -end $IPRange.EndAddress foreach($IP in $Range){ $RangeReport += $IP } } } $obj.IPRangeCount = $RangeReport.Count $EdgeReport += $obj } } $EdgeReport }
#LongLiveVCD