core/Resources/Scripts/new_cache.ps1
param( [Parameter(Mandatory = $true)] [string]$EnvironmentName, [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [ValidateSet("Replicated", "Partitioned", "PartitionReplica")] [string]$Topology, [Parameter(Mandatory = $true)] [long]$Size, [Parameter(Mandatory = $false)] [int]$CleanupInterval, [Parameter(Mandatory = $false)] [int]$ClusterPort, [Parameter(Mandatory = $false)] [string]$DefaultPriority, [Parameter(Mandatory = $false)] [string]$EvictionPolicy, [Parameter(Mandatory = $false)] [decimal]$EvictionRatio, [Parameter(Mandatory = $false)] [string]$SerializationFormat, [Parameter(Mandatory = $false)] [switch]$NoLogo, [Parameter(Mandatory = $false)] [string]$Path, [Parameter(Mandatory = $false)] [int]$Port, [Parameter(Mandatory = $false)] [string]$ReplicationStrategy, [Parameter(Mandatory = $false)] [PSCredential]$Credentials, [Parameter(Mandatory = $false)] [string]$InMemoryStoreType, [Parameter(Mandatory = $false)] [switch]$UseExistingIndex, [Parameter(Mandatory = $false)] [string]$PersistenceStoreName, [Parameter(Mandatory = $false)] [switch]$NewPersistenceStore, [Parameter(Mandatory = $false)] [string]$PersistenceStoreConnectionString, [string]$ScriptsFolderPath = ".\Resources\Scripts" ) . "$ScriptsFolderPath\dashboard_common.ps1" function Get-EnvName { param ( [Parameter(Mandatory = $true)] [string]$EnvironmentName ) # Get all RGs with EnvironmentName tag $all_resource_groups = Get-AzResourceGroup -ErrorAction Stop | Where-Object { $_.Tags -and $_.Tags.ContainsKey("EnvironmentName") } if (-not $all_resource_groups) { throw "No resource groups found with tag 'EnvironmentName'." } # Match the exact EnvironmentName $matched_group = $all_resource_groups | Where-Object { $_.Tags["EnvironmentName"] -eq $EnvironmentName } if (-not $matched_group) { throw "No resource group found with EnvironmentName = '$EnvironmentName'." } return $matched_group.ResourceGroupName } function GetVms { Param( [Parameter(Mandatory = $true)] [string]$EnvironmentName ) #Filtering VMs using ResourceGroups and Cache Tags $vms = Get-AzVM -Status -ResourceGroupName $EnvironmentName -ErrorAction Stop | Where-Object { $_.Tags.ContainsKey("Caches") } return $vms } function Get-VMPrivateIps { param( [Parameter(Mandatory = $true)] [array]$VMs, [Parameter(Mandatory = $true)] [string]$ResourceGroupName ) $VMPrivateIps = foreach ($vm in $VMs) { foreach ($nicRef in $vm.NetworkProfile.NetworkInterfaces) { $nicName = ($nicRef.Id -split "/")[-1] $nic = Get-AzNetworkInterface -Name $nicName -ResourceGroupName $ResourceGroupName -ErrorAction Stop [PSCustomObject]@{ VMName = $vm.Name NicName = $nic.Name PrivateIps = ($nic.IpConfigurations | Select-Object -ExpandProperty PrivateIpAddress) OsType = $vm.StorageProfile.OsDisk.OsType } } } return , $VMPrivateIps } function Get-LinuxCommand { param( [Parameter(Mandatory = $true)] [object]$machineInfo, [Parameter(Mandatory = $true)] [string]$cacheName ) $ipList = ($machineInfo.PrivateIps -join ",") $command = "/opt/ncache/bin/tools/new-cache $($cacheName) -server `"$ipList`" -topology $($Topology) -size $($Size)" if ($ClusterPort) { $command += " -clusterport $ClusterPort" } if ($DefaultPriority) { $command += " -defaultpriority $DefaultPriority" } if ($EvictionPolicy) { $command += " -evictionpolicy $EvictionPolicy" } if ($EvictionRatio) { $command += " -evictionratio $EvictionRatio" } if ($Inproc) { $command += " -inproc" } if ($CleanupInterval) { $command += " -cleanupinterval $CleanupInterval" } if ($Credentials) { $command += " -userid $($Credentials.UserName)" } if ($SerializationFormat) { $command += " -serializationformat $SerializationFormat" } if ($ReplicationStrategy) { $command += " -replicationstrategy $ReplicationStrategy" } if ($InMemoryStoreType) { $command += " -inmemorystoretype $InMemoryStoreType" } if ($UseExistingIndex) { $command += " -useexistingindex" } if ($PersistenceStoreName) { $command += " -persistencestorename $PersistenceStoreName" } if ($NewPersistenceStore) { $command += " -newpersistencestore" } if ($PersistenceStoreConnectionString) { $command += " -persistencestoreconnectionstring `"$PersistenceStoreConnectionString`"" } if ($Port) { $command += " -port $Port" } if ($NoLogo) { $command += " -nologo" } if ($Path) { if (Test-Path $Path) { #vmPath $vmPath = "./config-temp.ncconf" # Load file content into a variable $configContent = Get-Content -Path $Path -Raw # (Optional) Save it to ./config.nconf if needed $command = "echo `'$configContent`' > $vmPath ;" + $command # Prepend the -Path flag to the command $command += " -path $vmPath" $command += "; rm -f $vmPath" } else { throw "The specified path '$Path' does not exist." } } return $command } function Get-WindowsCommand { param( [Parameter(Mandatory = $true)] [object]$machineInfo, [Parameter(Mandatory = $true)] [string]$cacheName ) $ipList = ($machineInfo.PrivateIps -join ",") $command = "New-Cache -Name $($cacheName) -Server `"$ipList`" -Topology $($Topology) -Size $($Size)" if ($ClusterPort) { $command += " -ClusterPort $ClusterPort" } if ($DefaultPriority) { $command += " -DefaultPriority $DefaultPriority" } if ($EvictionPolicy) { $command += " -EvictionPolicy $EvictionPolicy" } if ($EvictionRatio) { $command += " -EvictionRatio $EvictionRatio" } if ($Inproc) { $command += " -InProc" } if ($CleanupInterval) { $command += " -CleanupInterval $CleanupInterval" } if ($Credentials) { $command += " -UserName $($Credentials.UserName)" # Password usually handled as SecureString } if ($SerializationFormat) { $command += " -SerializationFormat $SerializationFormat" } if ($ReplicationStrategy) { $command += " -ReplicationStrategy $ReplicationStrategy" } if ($InMemoryStoreType) { $command += " -InMemoryStoreType $InMemoryStoreType" } if ($UseExistingIndex) { $command += " -UseExistingIndex" } if ($LuceneIndexPath) { $command += " -LuceneIndexPath `"$LuceneIndexPath`"" } if ($PersistenceStoreName) { $command += " -PersistenceStoreName $PersistenceStoreName" } if ($NewPersistenceStore) { $command += " -NewPersistenceStore" } if ($PersistenceStoreConnectionString) { $command += " -PersistenceStoreConnectionString `"$PersistenceStoreConnectionString`"" } if ($Port) { $command += " -Port $Port" } if ($NoLogo) { $command += " -NoLogo" } if ($Path) { if (Test-Path $Path) { # vmPath $vmPath = ".\config-temp.ncconf" # Load file content into a variable $configContent = Get-Content -Path $Path -Raw # Save it to config-temp.nconf $command = "Set-Content -Path $vmPath -Value `'$configContent`'; " + $command # Prepend the -Path flag to the command $command = "$command -Path `"$vmPath`"" # Clean up the temp file after execution $command += "; Remove-Item -Force $vmPath" } else { throw "The specified path '$Path' does not exist." } } return $command } function Get-CommandForCache { param( [Parameter(Mandatory = $true)] [object]$machineInfo, [Parameter(Mandatory = $true)] [string]$cacheName ) if ($machineInfo.OsType -eq "Windows") { return @{ CommandId = "RunPowerShellScript" VMName = $machineInfo.FirstVMName Script = Get-WindowsCommand -machineInfo $machineInfo -cacheName $cacheName } } elseif ($machineInfo.OsType -eq "Linux") { return @{ CommandId = "RunShellScript" VMName = $machineInfo.FirstVMName Script = Get-LinuxCommand -machineInfo $machineInfo -cacheName $cacheName } } else { throw "Unknown OS type for VM: $($Vm.Name)" } } function Get-MachineInfo { param( [Parameter(Mandatory = $true)] [array]$VMInfo ) if (-not $VMInfo -or $VMInfo.Count -eq 0) { throw "VMInfo array is empty." } $firstVM = $VMInfo[0] # Aggregate all IPs from all VMs into a single array $allIPs = $VMInfo | ForEach-Object { $_.PrivateIps } | ForEach-Object { $_ } [PSCustomObject]@{ FirstVMName = $firstVM.VMName PrivateIps = $allIPs OsType = $firstVM.OsType } } function Add-CacheTagToVMs { param( [Parameter(Mandatory = $true)] [string]$ResourceGroupName, [Parameter(Mandatory = $true)] [string]$CacheName, [Parameter(Mandatory = $true)] [array]$VMs # array of VM objects with .Name ) foreach ($vm in $VMs) { try { Write-Output "Updating tags for VM: $($vm.Name)" # Get existing VM $vmResource = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $vm.VMName # Convert tags dictionary to hashtable $tags = @{} if ($vmResource.Tags) { foreach ($k in $vmResource.Tags.Keys) { $tags[$k] = $vmResource.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 } # Apply updated tags Set-AzResource -ResourceId $vmResource.Id -Tag $tags -Force -ErrorAction Stop | Out-Null Write-Output "Cache '$CacheName' added to VM '$($vm.VMName)'" } catch { Write-Output "Failed to update tags on $($vm.VMName): $_" } } Update-NcAzDashboards -ScriptsFolderPath $ScriptsFolderPath -ResourceGroupName $ResourceGroupName -CacheName $CacheName -SkipClient } function Invoke-CacheCommand { param( [Parameter(Mandatory = $true)] [string]$ResourceGroupName, [Parameter(Mandatory = $true)] [object]$Command ) Write-Output "Executing on VM: $($Command.VMName) => $($Command.Script)" $result = Invoke-AzVMRunCommand ` -ResourceGroupName $ResourceGroupName ` -VMName $Command.VMName ` -CommandId $Command.CommandId ` -ScriptString $Command.Script # Aggregate all Messages into a single string $messages = $result.Value | ForEach-Object { $_.Message } $joined = ($messages -join "`n").Trim() # Detect error from result codes $hasError = $false if ($Command.CommandId -eq "RunPowerShellScript" -and $result.Value | Where-Object { $_.Code -match "StdErr" -and -not [string]::IsNullOrWhiteSpace($_.Message) }) { $hasError = $true } elseif ($Command.CommandId -eq "RunShellScript" ) { $message = $result.Value[0].Message if ($message -match "Error:" -or $message -match "error:") { $hasError = $true } $parts = $message -split "\[stderr\]" # If there's something after [stderr], treat it as error$res if ($parts.Count -gt 1 -and $parts[1].Trim().Length -gt 0) { $hasError = $true } } # Build and return structured PSObject $status = if ($hasError) { "error" } else { "success" } [PSCustomObject]@{ status = $status message = $joined } } function View-CommandResult { param( [Parameter(Mandatory = $true)] [pscustomobject]$Result ) if ($Result.status -eq "error") { Write-Host $Result.message -ForegroundColor Red } else { Write-Host $Result.message } } function ExecuteCommands { $EnvironmentName = Get-EnvName -EnvironmentName $EnvironmentName #Get Vms with Given Caches $vms = GetVms -EnvironmentName $EnvironmentName #Check If VM Exists or not if (-not $vms -or $vms.Count -eq 0) { throw "No Server Exists To Create New Cache" } #Get Private IPs of Vms (VM Name, CachesList, NicName, PrivateIps, OsType) $privateIps = Get-VMPrivateIps -VMs $vms -ResourceGroupName $EnvironmentName #Get Cache Groups (CacheName, FirstVM, OsType, PrivateIps) $machine = Get-MachineInfo -VmInfo $privateIps #Get Commands to be Executed on Azure $command = Get-CommandForCache -machineInfo $machine -cacheName $Name #Execute Commands $cmdExecution = Invoke-CacheCommand -ResourceGroupName $EnvironmentName -Command $command if ($cmdExecution.status -eq "success") { Write-Output "Adding Tags" Add-CacheTagToVMs -ResourceGroupName $EnvironmentName -CacheName $Name -VMs $privateIps } View-CommandResult -Result $cmdExecution } try { if (-not (Get-AzContext)) { Connect-AzAccount if (Get-AzContext) { Write-Output "Created Context, Creating New Cache..." ExecuteCommands } } else { Write-Output "Already have Context, Creating New Cache..." ExecuteCommands } } catch { Write-Error $($_.Exception.Message) Write-Error "Coudn't Create New Cache'" } |