framework/Resources/Scripts/new_client_cache.ps1

Param(
    [Parameter(Mandatory = $true)]
    [string]$EnvironmentName,

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

    [Parameter(Mandatory = $true)]
    [string]$ClientCacheName,

    [Parameter(Mandatory = $true)]
    [string]$Server,

    [int]$Size = 1024,

    [int]$Port = 8250,

    [ValidateSet("Regular", "FullData")]
    [string]$Type = "Regular",
    
    [ValidateSet("LRU", "LFU", "Priority")]
    [string]$EvictionPolicy = "LRU",
    
    [int]$CleanInterval = 15,   # in seconds
    
    [pscredential]$Credentials,
    
    [ValidateRange(1, 100)]
    [int]$EvictionRatio = 5,
    
    [ValidateSet("Low", "BelowNormal", "Normal", "AboveNormal", "High")]
    [string]$DefaultPriority = "Normal",
    
    [switch]$InProc,
    [switch]$Optimistic,
    [switch]$DisableL2FallbackOnMiss,
    [switch]$FailQueryOnPartialDataset,
    [switch]$UpdateServerConfig,
    [string]$ClientNode,
    [string]$ConfigPath,

    [string]$ScriptsFolderPath = ".\Resources\Scripts"
)

. "$ScriptsFolderPath\dashboard_common.ps1"

function GetUploadedVmNames {
    param(
        [Parameter(Mandatory)][string]$ResourceGroup
    )
    return Get-AzVM -ResourceGroupName $ResourceGroup -ErrorAction Stop |
    Where-Object { $_.Tags.ContainsKey("InstallMode") -and $_.Tags["InstallMode"] -eq "server" } |
    Select-Object -ExpandProperty Name 
}

function GetClientVMs {
    param(
        [Parameter(Mandatory)][string]$ResourceGroup
    )
    return Get-AzVM -ResourceGroupName $ResourceGroup -ErrorAction Stop |
    Where-Object { $_.Tags.ContainsKey("InstallMode") -and $_.Tags["InstallMode"] -eq "client" }
}

function Add-CacheTagAndDashboards {
    param(
        [object]$Resource
    )
    
    $clientVMs = GetClientVMs -ResourceGroup $Resource.ResourceGroupName
    foreach ($vm in $clientVMs) {
        try {
            # Convert tags dictionary to hashtable
            $tags = @{}
            if ($vm.Tags) {
                foreach ($k in $vm.Tags.Keys) {
                    $tags[$k] = $vm.Tags[$k]
                }
            }

            # Update/add "Caches" tag
            if ($tags.ContainsKey("Caches")) {
                if ($tags["Caches"] -notmatch "\b$CacheName\b") {
                    $tags["Caches"] = "$($tags["Caches"]),$CacheName"
                }
            }
            else {
                $tags["Caches"] = $CacheName
            }
            Set-AzResource -ResourceId $vm.Id -Tag $tags -Force -ErrorAction Stop | Out-Null
        }
        catch {
            Write-Output "Failed to update tags on $($vm.Name): $_"
        }
    }

    Update-NcAzDashboards -ScriptsFolderPath $ScriptsFolderPath -ResourceGroupName $Resource.ResourceGroupName -CacheName $CacheName -SkipServer
}

function InvokeCommandOnServerWindows {
    param(
        [string]$ResourceGroupName,
        [string[]]$VmNames
    )

    $script = "New-ClientCache -CacheName $($cacheName) -ClientCacheName $($ClientCacheName) -Server $($Server)"
    if ($Size) { 
        $script += " -Size $($Size)" 
    }
    if ($Port) {
        $script += " -Port $($Port)" 
    }
    if ($Type) { 
        $script += " -Type $($Type)"
    }
    if ($EvictionPolicy) { 
        $script += " -EvictionPolicy $($EvictionPolicy)" 
    }
    if ($CleanInterval) {
        $script += " -CleanupInterval $($CleanInterval)"
    }
    if ($Credentials) { 
        $script += " -Credentials (New-Object System.Management.Automation.PSCredential('$($Credentials.UserName)', (ConvertTo-SecureString '$($Credentials.GetNetworkCredential().Password)' -AsPlainText -Force)))" 
    }
    if ($EvictionRatio) {
        $script += " -EvictionRatio $($EvictionRatio)" 
    }
    if ($DefaultPriority) {
        $script += " -DefaultPriority $($DefaultPriority)" 
    }
    if ($InProc) {
        $script += " -InProc" 
    }
    if ($Optimistic) { 
        $script += " -Optimistic"
    }
    if ($DisableL2FallbackOnMiss) {
        $script += " -DisableL2FallbackOnMiss"
    }
    if ($FailQueryOnPartialDataset) {
        $script += " -FailQueryOnPartialDataset" 
    }
    if ($UpdateServerConfig) {
        $script += " -UpdateServerConfig" 
    }
    if ($ClientNode) { 
        $script += " -ClientNode '$($ClientNode)'"
    }
    if ($ConfigPath) {
        if (Test-Path $ConfigPath) {

            # vmPath
            $vmPath = ".\config-temp.ncconf"

            # Load file content into a variable
            $configContent = Get-Content -Path $ConfigPath -Raw

            # Save it to config-temp.nconf
            $script = "Set-Content -Path $vmPath -Value `'$configContent`'; " + $script 

            # Prepend the -Path flag to the command
            $script = "$script -Path `"$vmPath`""

            # Clean up the temp file after execution
            $script += "; Remove-Item -Force $vmPath"
        }
        else {
            throw "The specified path '$ConfigPath' does not exist."
        }
    }
    # run this on only 1 VM, and this will be added on the server specified in -Server parameter
    $vm = $VmNames[0]
    $result = Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $vm -CommandId 'RunPowerShellScript' -ScriptString $script

    foreach ($val in $result.Value) {
        Write-Host $val.Message
    }

    return $result.Status
}

function InvokeCommandOnServerLinux {
    param(
        [string]$ResourceGroupName,
        [string[]]$VmNames
    )

    $script = "/opt/ncache/bin/tools/new-clientcache -cachename $($cacheName) -clientcachename $($ClientCacheName) -server $($Server)"
    if ($Size) { 
        $script += " -size $($Size)"
    }
    if ($Port) {
        $script += " -port $($Port)"
    }
    if ($Type) { 
        $script += " -type $($Type)" 
    }
    if ($EvictionPolicy) { 
        $script += " -evictionpolicy $($EvictionPolicy)"
    }
    if ($CleanInterval) { 
        $script += " -cleanupinterval $($CleanInterval)"
    }
    if ($Credentials) { 
        $script += " -credentials (New-Object System.Management.Automation.PSCredential('$($Credentials.UserName)', (ConvertTo-SecureString '$($Credentials.GetNetworkCredential().Password)' -AsPlainText -Force)))"
    }
    if ($EvictionRatio) {
        $script += " -evictionratio $($EvictionRatio)"
    }
    if ($DefaultPriority) { 
        $script += " -defaultpriority $($DefaultPriority)"
    }
    if ($InProc) {
        $script += " -inproc" 
    }
    if ($Optimistic) {
        $script += " -optimistic"
    }
    if ($DisableL2FallbackOnMiss) { 
        $script += " -disablel2fallbackonmiss" 
    }
    if ($FailQueryOnPartialDataset) {
        $script += " -failqueryonpartialdataset"
    }
    if ($UpdateServerConfig) { 
        $script += " -updateserverconfig"
    }
    if ($ClientNode) {
        $script += " -clientnode '$($ClientNode)'"
    }
    if ($ConfigPath) {
        if (Test-Path $ConfigPath) {

            #vmPath
            $vmPath = "./config-temp.ncconf"
            # Load file content into a variable
            $configContent = Get-Content -Path $ConfigPath -Raw

            # (Optional) Save it to ./config.nconf if needed
            $script = "echo `'$configContent`' > $vmPath ;" + $script

            # Prepend the -Path flag to the command
            $script += " -path $vmPath"


            $script += "; rm -f $vmPath"
        }
        else {
            throw "The specified path '$ConfigPath' does not exist."
        }
    }
    # run this on only 1 VM, and this will be added on the server specified in -Server parameter
    $vm = $VmNames[0]
    $result = Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $vm -CommandId 'RunShellScript' -ScriptString $script

    foreach ($val in $result.Value) {
        Write-Host $val.Message
    }

    return $result.Status
}

function InvokeCommandOnVms {
    param(
        [object]$Resource,
        [string[]]$VmNames
    )

    $os = $Resource.Tags['OsType']
    if ($os -eq "Windows") {
        return InvokeCommandOnServerWindows -ResourceGroupName $resource.ResourceGroupName -VmNames $VmNames
    }
    else {
        return InvokeCommandOnServerLinux -ResourceGroupName $resource.ResourceGroupName -VmNames $VmNames
    }
}

function ExecuteCommands {
    $resource = Get-AzResourceGroup -ErrorAction Stop | Where-Object { $_.Tags -and $_.Tags.Contains("EnvironmentName") -and $_.Tags["EnvironmentName"] -eq $EnvironmentName }
    if (-not $resource) {
        throw "No such environment exists"
    }

    $vmNames = GetUploadedVmNames -ResourceGroup $resource.ResourceGroupName

    $status = InvokeCommandOnVms -Resource $resource -VmNames $vmNames

    if ($status -eq "Succeeded") {
        Add-CacheTagAndDashboards -Resource $Resource
    }
}

try {
    if (-not (Get-AzContext)) {
        Connect-AzAccount
        if (Get-AzContext) {
            ExecuteCommands
        }
    }
    else {
        ExecuteCommands
    }
}
catch {
    Write-Error $($_.Exception.Message)
}