Grafana Dashboard for vCloud Director

One of the points on my bucket list for 2018 was to learn more about Grafana. So I decided to create my own Grafana Dashboard for vCloud Director. Like my vCloud Director Tenant HTML Report should the Dashboard also work from Tenant perspective. As further requirements I have decided that Ubuntu should be the platform and no external data sources should be required.

With this list of requirement I did some research to find the best fitting tools. I decided to use InfluxDB as Data Source for Grafana and Telegraf as Collector Agent. Telegraf uses Input Plugins to gather data. With the Exec Input Plugin Telegraf is able to execute a script and use the output as metric data. With PowerShell Core multi-platform support also a PowerShell script is possible, which is my preferred scripting language.

Collection Process:

  1. PowerShell Script utilizes the vCloud Director RESTful API to create metrics and tags
  2. Telegraf collects output of the Script
  3. Telegraf pushed the metrics and tags  into InfluxDB
  4. Grafana Dashboard used metrics and tags from InfluxDB

Jorge de la Cruz created a great diagram of the Grafana collection workflow in his blog post: Looking for the Perfect Dashboard: InfluxDB, Telegraf and Grafana – Part VIII (Monitoring Veeam using Veeam Enterprise Manager)

Backend of the Grafana Dashboard for vCloud Director

I will give a quick wrap up of my installation on my Ubuntu 16.04 box.

InfluxDB

Add repository:

curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add -
source /etc/lsb-release
echo "deb https://repos.influxdata.com/${DISTRIB_ID,,} ${DISTRIB_CODENAME} stable" | sudo tee /etc/apt/sources.list.d/influxdb.list

Install InfluxDB:

sudo apt-get update && sudo apt-get install influxdb

Start and enable service:

sudo systemctl enable influxdb  
sudo systemctl start influxdb

Create InfluxDB user and database:

You need to enter Influx Shell first:influx

CREATE USER admin WITH PASSWORD '<Your Password>!' WITH ALL PRIVILEGES  
CREATE DATABASE telegraf  
exit

Grafana Dashboard for vCloud Director - Create User and DB

Configure connection:

Connection details need to be configured in influxdb.conf : sudo vi /etc/influxdb/influxdb.conf

[http]   
  enabled = true   
  bind-address = ":8086"   
  auth-enabled = true

Grafana Dashboard for vCloud Director - Configure Connection

Restart service:

sudo systemctl restart influxdb

Telegraf

Install Telegraf and prerequirements:

sudo apt-get install telegraf snmp snmp-mibs-downloader

Use all installed MIBs:

You need to modify the snmp.confsudo vi /etc/snmp/snmp.conf

mibs +ALL

Configure output:

The output setting in telegraf.conf must match the InfluxDB configuration: sudo vi /etc/telegraf/telegraf.conf

[[outputs.influxdb]]
  urls = ["http://127.0.0.1:8086"] # required
  database = "telegraf" # required
  retention_policy = ""
  write_consistency = "any"
  timeout = "5s"
  username = "admin"
  password = "<Password>"

Grafana Dashboard for vCloud Director - Configure output

Grafana

Add repository:

echo "deb https://packagecloud.io/grafana/stable/debian/ jessie main" | sudo tee /etc/apt/sources.list.d/grafana.list
curl https://packagecloud.io/gpg.key | sudo apt-key add -

Install Grafana:

sudo apt-get update && sudo apt-get install grafana

You are now able to access the Grafana site via http://<Yout IP>:3000 and configure the InfluxDB data source:

Grafana Dashboard for vCloud Director - Configure InfluxDB Data Source

Grafana Dashboard for vCloud Director - Configure InfluxDB Data Source Details

PowerShell

Add repository:

curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list | sudo tee /etc/apt/sources.list.d/microsoft.list

Install PowerShell:

sudo apt-get update && sudo apt-get install powershell

Configuration of the Grafana Dashboard for vCloud Director

Telegraf

Just append a new section to the telegraf.conf : sudo vi /etc/telegraf/telegraf.conf

[[inputs.exec]]
  commands = ["pwsh /scripts/Grafana-Telegraf-vCloud-PsCore/vCloud.ps1"]
  name_override = "vCloudStats"
  interval = "60s"
  timeout = "60s"
  data_format = "influx"

PowerShell Script

To run the Script a json file for the configuration is needed in addition. Both files (config only as example) are available in my GitHub Repository Grafana-Telegraf-vCloud-PsCore. I typically use git to sync the script between my workstation and the Grafana box: just use initially  git clone https://github.com/mycloudrevolution/Grafana-Telegraf-vCloud-PsCore.git and for updates git pull

$ConfigFile = "$PSScriptRoot/Config.json"
$Configs = Get-Content -Raw -Path $ConfigFile -ErrorAction Continue | ConvertFrom-Json -ErrorAction Continue

if (!($Configs)) {
    Throw "Import JSON Config Failed"
    }

$VcdHost = $Configs.Base.VcdHost
$BasicAuth = $Configs.Base.BasicAuth

#region: Login
$Uri = "https://$VcdHost/api/sessions"
$Authorization = 'Basic {0}' -f $BasicAuth
$Headers =  @{'accept' = 'application/vnd.vmware.vcloud.session+xml;version=27.0'; 'Authorization' = $Authorization}
$ResponseHeaders = $null
$Login = Invoke-RestMethod -uri $Uri -Method Post -Headers $Headers -ResponseHeadersVariable 'ResponseHeaders'
#endregion

#region: Cleanup Confidential Data
Clear-Variable -Name BasicAuth, Authorization, Headers
#endregion

#region: Get vApps
$Uri = "https://$VcdHost/api/query?type=orgVdc"
$Headers =  @{'accept' = 'application/*+xml;version=27.0'; 'x-vcloud-authorization' = [String]$ResponseHeaders.'x-vcloud-authorization'}
[XML]$orgVdcs = Invoke-RestMethod -uri $Uri -Method Get -Headers $Headers
#endregion

#region: Get vApps
$Uri = "https://$VcdHost/api/query?type=vApp"
$Headers =  @{'accept' = 'application/*+xml;version=27.0'; 'x-vcloud-authorization' = [String]$ResponseHeaders.'x-vcloud-authorization'}
[XML]$vApps = Invoke-RestMethod -uri $Uri -Method Get -Headers $Headers
#endregion

#region: Get VMs
$Uri = "https://$VcdHost/api/query?type=vm"
$Headers =  @{'accept' = 'application/*+xml;version=27.0'; 'x-vcloud-authorization' = [String]$ResponseHeaders.'x-vcloud-authorization'}
[XML]$VMs = Invoke-RestMethod -uri $Uri -Method Get -Headers $Headers
#endregion

#region: Get orgNetworks
$Uri = "https://$VcdHost/api/query?type=orgNetwork"
$Headers =  @{'accept' = 'application/*+xml;version=27.0'; 'x-vcloud-authorization' = [String]$ResponseHeaders.'x-vcloud-authorization'}
[XML]$orgNetworks = Invoke-RestMethod -uri $Uri -Method Get -Headers $Headers
#endregion

#region: Get edgeGateway
$Uri = "https://$VcdHost/api/query?type=edgeGateway"
$Headers =  @{'accept' = 'application/*+xml;version=27.0'; 'x-vcloud-authorization' = [String]$ResponseHeaders.'x-vcloud-authorization'}
[XML]$edgeGateways = Invoke-RestMethod -uri $Uri -Method Get -Headers $Headers
#endregion

#region: Output
## Simple Stats
$orgVdcsTotal = ([Array]$orgVdcs.QueryResultRecords.OrgVdcRecord).Count
$body="vCloudStats orgVdcCountTotal=$orgVdcsTotal"
Write-Host $body
$vAppsTotal = ([Array]$vApps.QueryResultRecords.VAppRecord).Count
$body="vCloudStats vAppCountTotal=$vAppsTotal"
Write-Host $body
$VMsTotal = ([Array]$VMs.QueryResultRecords.VMRecord | Where-Object {$_.isVAppTemplate -ne "true"}).Count
$body="vCloudStats VMCountTotal=$VMsTotal"
Write-Host $body
$VMsPoweredOff = ([Array]$VMs.QueryResultRecords.VMRecord | Where-Object {$_.isVAppTemplate -ne "true" -and  $_.status -eq "POWERED_OFF"}).Count
$body="vCloudStats VMCountPoweredOff=$VMsPoweredOff"
Write-Host $body
$orgNetworksTotal = $orgNetworks.QueryResultRecords.OrgNetworkRecord.Count
$body="vCloudStats orgNetworkCountTotal=$orgNetworksTotal"
Write-Host $body
$edgeGatewaysTotal = ([Array]$edgeGateways.QueryResultRecords.EdgeGatewayRecord).Count
$body="vCloudStats edgeGatewaysTotal=$edgeGatewaysTotal"
Write-Host $body

## OrgVdc Details
foreach ($item in [Array]$orgVdcs.QueryResultRecords.OrgVdcRecord) {
    $body = "vCloudStats,orgVdc=$($item.name),isEnabled=$($item.isEnabled) cpuUsedMhz=$($item.cpuUsedMhz),memoryUsedMB=$($item.memoryUsedMB),numberOfMedia=$($item.numberOfMedia),numberOfVAppTemplates=$($item.numberOfVAppTemplates),numberOfVApps=$($item.numberOfVApps),storageUsedMB=$($item.storageUsedMB)"
        Write-Host $body
}
## vApp Details
foreach ($item in [Array]$vApps.QueryResultRecords.VAppRecord) {
    $body = "vCloudStats,vApp=$($item.name),status=$($item.status) numberOfVMs=$($item.numberOfVMs),numberOfCpus=$($item.numberOfCpus),cpuAllocationInMhz=$($item.cpuAllocationInMhz),memoryAllocationMB=$($item.memoryAllocationMB),storageKB=$($item.storageKB)"
        Write-Host $body
}
## orgNetwork Details
foreach ($item in [Array]$orgNetworks.QueryResultRecords.OrgNetworkRecord) {
    $Uri = [string]$item.href + "/allocatedAddresses"
    $Headers =  @{'accept' = 'application/*+xml;version=27.0'; 'x-vcloud-authorization' = [String]$ResponseHeaders.'x-vcloud-authorization'}
    [XML]$orgNetworkAllocated = Invoke-RestMethod -uri $Uri -Method Get -Headers $Headers
    $AllocatedIpAddressesTotal = $orgNetworkAllocated.AllocatedIpAddresses.IpAddress.Count
    $body = "vCloudStats,orgNetwork=$($item.name),gateway=$($item.gateway) AllocatedIpAddressesTotal=$AllocatedIpAddressesTotal"
        Write-Host $body
}
## Edge Details
foreach ($item in [Array]$edgeGateways.QueryResultRecords.EdgeGatewayRecord) {
    $body = "vCloudStats,edgeGateway=$($item.name),gatewayStatus=$($item.gatewayStatus),haStatus=$($item.haStatus) numberOfExtNetworks=$($item.numberOfExtNetworks),numberOfOrgNetworks=$($item.numberOfOrgNetworks)"
        Write-Host $body
}
#endregion

#region: Logout
$Uri = "https://$VcdHost/api/session"
$Headers =  @{'accept' = 'application/vnd.vmware.vcloud.session+xml;version=27.0'; 'x-vcloud-authorization' = [String]$ResponseHeaders.'x-vcloud-authorization'}
$Logout = Invoke-RestMethod -uri $Uri -Method Delete -Headers $Headers
#endregion

#region: Cleanup Confidential Data
Clear-Variable -Name ResponseHeaders, Headers
#endregion

The json configuration contains the FQDN of the vCloud Director instance and the Base64 Hash of Username and Password.

{
    "Base": {
            "VcdHost": "<FQDN>",
            "BasicAuth": "<Base64>"
        }
    }

Note:

The un-hashed username format needs to be: <User>@<Org>

The Base64 hash can be created with a simple PowerShell Script:

[String] $User		= "<User>@<Org>"
[String] $Password	= "<Password>"	
Write-Host "Basic String: " $([Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$($user):$($password)")))

Details of Grafana Dashboard for vCloud Director

The Dashboard has at the moment four different sections, Summary, OrgVdc Usage, vApp Usage and Org Network / Edge Gateway Usage.

Summary

The Summary section shows the most import stats of your organization.

Grafana Dashboard for vCloud Director - Dashboard Summary

OrgVdc Usage

In this section the resource usage per OrgVdc is visualized.

Grafana Dashboard for vCloud Director - Dashboard OrgVdc

vApp Usage

In this section the storage usage of all vApp and CPU und RAM usage of powered on vApps is visualized.

Grafana Dashboard for vCloud Director - Dashboard vApp

Org Network and Edge Gateway Usage

This sections visualizes the IP allocation per Org Network and number of connected networks per Edge Gateway.

Grafana Dashboard for vCloud Director - Dashboard Org Net and Edge Gateway

 

8 Comments

  1. Dany 11. April 2018
  2. defmond law 12. February 2019
    • Markus Kraus 12. February 2019
  3. Defmond LAW 12. February 2019
    • Markus Kraus 12. February 2019
  4. gan 8. January 2023
    • Markus Kraus 10. January 2023

Leave a Reply