frameworkResources/Scripts/dashboard_common.ps1

function Update-NcAzDashboards {
    param(
        [string]$ScriptsFolderPath = ".\Resources\Scripts",
        [string]$ResourceGroupName,
        [string]$CacheName,
        [switch]$SkipServer,
        [switch]$SkipClient
    )
    
    # Get RG object
    $rg = Get-AzResourceGroup -Name $ResourceGroupName

    # SubscriptionId
    $SubscriptionId = (Get-AzContext).Subscription.Id

    # Location of the RG
    $Location = $rg.Location

    # OsType tag value from RG
    $osType = $null
    if ($rg.Tags.ContainsKey("OsType")) {
        $osType = $rg.Tags["OsType"]
    }

    $allVMs = Get-AzVM -ResourceGroupName $ResourceGroupName -ErrorAction Stop |
    Where-Object {
        $_.Tags.ContainsKey("InstallMode") -and
        $_.Tags.ContainsKey("Caches") -and
        ($_.Tags["Caches"] -split ',' | ForEach-Object { $_.Trim() }) -contains $CacheName
    }

    if ($allVMs) {
        $results = @()

        $reportDashRes = New-NcAzReportDashboard `
            -ScriptsFolderPath $ScriptsFolderPath `
            -ResourceGroupName $ResourceGroupName `
            -SubscriptionId $SubscriptionId `
            -CacheName $CacheName `
            -Location $Location `
            -OS $osType `
            -VMs $allVMs

        if ($reportDashRes) {
            $results += $reportDashRes
        }

        $serverVMs = $allVMs | Where-Object { $_.Tags["InstallMode"] -eq "server" } | Select-Object -ExpandProperty Name
        if ($serverVMs -and !$SkipServer) {
            $serverDashRes = New-NcAzServerDashboard `
                -ScriptsFolderPath $ScriptsFolderPath `
                -ResourceGroupName $ResourceGroupName `
                -SubscriptionId $SubscriptionId `
                -CacheName $CacheName `
                -Location $Location `
                -OS $osType `
                -VMs $serverVMs

            if ($serverDashRes) {
                $results += $serverDashRes
            }
        }
    
        $clientVMs = $allVMs | Where-Object { $_.Tags["InstallMode"] -eq "client" } | Select-Object -ExpandProperty Name
        if ($clientVMs -and !$SkipClient) {
            $clientDashRes = New-NcAzClientDashboard `
                -ScriptsFolderPath $ScriptsFolderPath `
                -ResourceGroupName $ResourceGroupName `
                -SubscriptionId $SubscriptionId `
                -CacheName $CacheName `
                -Location $Location `
                -OS $osType `
                -VMs $clientVMs

            if ($clientDashRes) {
                $results += $clientDashRes
            }
        }

        Write-Output "Dashboards to monitor the cache stats:"
        $results | Format-List
    }
}

function New-NcAzReportDashboard {
    param(
        [string]$ScriptsFolderPath = ".\Resources\Scripts",

        [Parameter(Mandatory)]
        [string]$ResourceGroupName,

        [Parameter(Mandatory)]
        [string]$SubscriptionId,

        [Parameter(Mandatory)]
        [string]$CacheName,

        [Parameter(Mandatory)]
        [string]$Location,

        [Parameter(Mandatory)]
        [string]$OS,

        [array]$VMs
    )

    $reportDashBase = "$ScriptsFolderPath\DashboardTemplates\ReportDash_Base.json"
    $reportDashServerTile = "$ScriptsFolderPath\DashboardTemplates\$($OS)_ReportServer_Tile.json"
    $reportDashClientTile = "$ScriptsFolderPath\DashboardTemplates\$($OS)_ReportClient_Tile.json"
    
    $baseTemplate = Get-Content $reportDashBase -Raw
    $serverTileTemplate = Get-Content $reportDashServerTile -Raw
    $clientTileTemplate = Get-Content $reportDashClientTile -Raw
    $DashboardName = "Report_Dashboard_$CacheName"
    $EnvironmentName = $ResourceGroupName -replace "^NC-", ""

    $baseObj = $baseTemplate | ConvertFrom-Json

    if (-not $baseObj.properties.lenses[0].parts) {
        $baseObj.properties.lenses[0].parts = @()
    }

    $serverX = 0
    $clientX = 0

    foreach ($vm in $VMs) {
        $installMode = $vm.Tags["InstallMode"]

        if (-not $installMode) {
            continue
        }

        switch ($installMode.ToLower()) {
            "server" {
                $serverPartJson = $serverTileTemplate `
                    -replace "{{SUBSCRIPTION_ID}}", $SubscriptionId `
                    -replace "{{RESOURCE_GROUP_NAME}}", $ResourceGroupName `
                    -replace "{{VM_NAME}}", $vm.Name `
                    -replace "{{CACHE_NAME}}", $CacheName

                $serverObj = $serverPartJson | ConvertFrom-Json
                $serverObj.position.x = $serverX
                $baseObj.properties.lenses[0].parts += $serverObj
                # increment X for next tile
                $serverX += 4
            }
            "client" {
                $clientPartJson = $clientTileTemplate `
                    -replace "{{SUBSCRIPTION_ID}}", $SubscriptionId `
                    -replace "{{RESOURCE_GROUP_NAME}}", $ResourceGroupName `
                    -replace "{{VM_NAME}}", $vm.Name `
                    -replace "{{CACHE_NAME}}", $CacheName

                $clientObj = $clientPartJson | ConvertFrom-Json
                $clientObj.position.x = $clientX
                $baseObj.properties.lenses[0].parts += $clientObj
                # increment X for next tile
                $clientX += 4
            }
            default {
            }
        }
    }

    $baseObj.name = $DashboardName
    $baseObj.tags."hidden-title" = "Report Dashboard ($CacheName) - $EnvironmentName"
    $baseObj.location = $Location
    $finalJson = $baseObj | ConvertTo-Json -Depth 100 -Compress

    try {
        $dashboard = New-AzPortalDashboard `
            -Name $DashboardName `
            -ResourceGroupName $ResourceGroupName `
            -JsonString $finalJson -ErrorAction Stop

        return [PSCustomObject]@{
            DashboardName = $DashboardName
            Link          = "https://portal.azure.com/#dashboard/arm$($dashboard.Id)"
        }
    }
    catch {
        Write-Error "Failed to create $($DashboardName): $($_.Exception.Message)"
        return $null
    }
}

function New-NcAzServerDashboard {
    param(
        [string]$ScriptsFolderPath = ".\Resources\Scripts",

        [Parameter(Mandatory)]
        [string]$ResourceGroupName,

        [Parameter(Mandatory)]
        [string]$SubscriptionId,

        [Parameter(Mandatory)]
        [string]$CacheName,

        [Parameter(Mandatory)]
        [string]$Location,

        [Parameter(Mandatory)]
        [string]$OS,

        [array]$VMs
    )

    $serverDashBase = "$ScriptsFolderPath\DashboardTemplates\$($OS)_ServerDash_Base.json"
    
    $baseTemplate = Get-Content $serverDashBase -Raw
    $baseTemplate = $baseTemplate -replace "{{CACHE_NAME}}", $CacheName
    $baseObj = $baseTemplate | ConvertFrom-Json
    $DashboardName = "Server_Dashboard_$CacheName"
    $EnvironmentName = $ResourceGroupName -replace "^NC-", ""

    foreach ($part in $baseObj.properties.lenses[0].parts) {
        $metricName = $part.metadata.inputs[0].value.chart.metrics[0].name

        $newMetrics = @()
        foreach ($vm in $VMs) {
            $namespace = Get-NcAzNamespace -OS $OS -MetricName $metricName

            $metricTemplate = @{
                resourceMetadata    = @{
                    id = "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.Compute/virtualMachines/$vm"
                }
                name                = $metricName
                aggregationType     = 4
                namespace           = $namespace
                metricVisualization = @{
                    displayName         = $metricName
                    resourceDisplayName = $vm
                }
            }
            $newMetrics += $metricTemplate
        }

        $part.metadata.inputs[0].value.chart.metrics = $newMetrics
        $part.metadata.settings.content.options.chart.metrics = $newMetrics
    }

    $baseObj.name = $DashboardName
    $baseObj.tags."hidden-title" = "Server Dashboard ($CacheName) - $EnvironmentName"
    $baseObj.location = $Location
    $finalJson = $baseObj | ConvertTo-Json -Depth 100 -Compress

    try {
        $dashboard = New-AzPortalDashboard `
            -Name $DashboardName `
            -ResourceGroupName $ResourceGroupName `
            -JsonString $finalJson -ErrorAction Stop

        return [PSCustomObject]@{
            DashboardName = $DashboardName
            Link          = "https://portal.azure.com/#dashboard/arm$($dashboard.Id)"
        }    
    }
    catch {
        Write-Error "Failed to create $($DashboardName): $($_.Exception.Message)"
        return $null
    }
}

function New-NcAzClientDashboard {
    param(
        [string]$ScriptsFolderPath = ".\Resources\Scripts",

        [Parameter(Mandatory)]
        [string]$ResourceGroupName,

        [Parameter(Mandatory)]
        [string]$SubscriptionId,

        [Parameter(Mandatory)]
        [string]$CacheName,

        [Parameter(Mandatory)]
        [string]$Location,

        [Parameter(Mandatory)]
        [string]$OS,

        [array]$VMs
    )

    $clientDashBase = "$ScriptsFolderPath\DashboardTemplates\$($OS)_ClientDash_Base.json"
    
    $baseTemplate = Get-Content $clientDashBase -Raw
    $baseTemplate = $baseTemplate -replace "{{CACHE_NAME}}", $CacheName
    $baseObj = $baseTemplate | ConvertFrom-Json
    $DashboardName = "Client_Dashboard_$CacheName"
    $EnvironmentName = $ResourceGroupName -replace "^NC-", ""

    foreach ($part in $baseObj.properties.lenses[0].parts) {
        $metricName = $part.metadata.inputs[0].value.chart.metrics[0].name

        $newMetrics = @()
        foreach ($vm in $VMs) {
            $namespace = Get-NcAzNamespace -OS $OS -MetricName $metricName -ClientDashboard

            $metricTemplate = @{
                resourceMetadata    = @{
                    id = "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.Compute/virtualMachines/$vm"
                }
                name                = $metricName
                aggregationType     = 4
                namespace           = $namespace
                metricVisualization = @{
                    displayName         = $metricName
                    resourceDisplayName = $vm
                }
            }
            $newMetrics += $metricTemplate
        }

        $part.metadata.inputs[0].value.chart.metrics = $newMetrics
        $part.metadata.settings.content.options.chart.metrics = $newMetrics
    }

    $baseObj.name = $DashboardName
    $baseObj.tags."hidden-title" = "Client Dashboard ($CacheName) - $EnvironmentName"
    $baseObj.location = $Location
    $finalJson = $baseObj | ConvertTo-Json -Depth 100 -Compress

    try {
        $dashboard = New-AzPortalDashboard `
            -Name $DashboardName `
            -ResourceGroupName $ResourceGroupName `
            -JsonString $finalJson -ErrorAction Stop

        return [PSCustomObject]@{
            DashboardName = $DashboardName
            Link          = "https://portal.azure.com/#dashboard/arm$($dashboard.Id)"
        }    
    }
    catch {
        Write-Error "Failed to create $($DashboardName): $($_.Exception.Message)"
        return $null
    }
}

function Remove-NcAzDashboards {
    param(
        [Parameter(Mandatory)]
        [string]$ResourceGroupName,

        [Parameter(Mandatory)]
        [string]$CacheName
    )
    
    Remove-AzPortalDashboard -ResourceGroupName $ResourceGroupName -DashboardName "Report_Dashboard_$CacheName"
    Remove-AzPortalDashboard -ResourceGroupName $ResourceGroupName -DashboardName "Server_Dashboard_$CacheName"
    Remove-AzPortalDashboard -ResourceGroupName $ResourceGroupName -DashboardName "Client_Dashboard_$CacheName"
}

function Get-NcAzNamespace {
    param (
        [string]$OS,
        [string]$MetricName,
        [switch]$ClientDashboard
    )
    $namespace = ""

    if ($OS -eq "Windows") {
        $namespace = "ncache-metrics*"
        if ($metricName -eq "Percent_Processor_Time") {
            $namespace = "ncache-metricswin_cpu"
        }
        if ($metricName -eq "Percent_Committed_Bytes_In_Use") {
            $namespace = "ncache-metricswin_mem"
        }
    }
    else {
        if ($ClientDashboard) {
            $namespace = "ncache-metricsncache..1.3.6.1.4.1.12.1.2.1.1"
        }
        else {
            $namespace = "ncache-metricsncache..1.3.6.1.4.1.12.1.1.1.1"
        }
        if ($metricName -eq "Available Memory Percentage" -or $metricName -eq "Percentage CPU") {
            $namespace = "microsoft.compute/virtualmachines"
        }
    }

    return $namespace
}