Private/nodes-functions.ps1
function Show-NodeConditions { param( [int]$PageSize = 10, # Number of nodes per page [switch]$html ) if (-not $Global:MakeReport -and -not $Html) { Clear-Host } Write-Host "`n[🌍 Node Conditions]" -ForegroundColor Cyan Write-Host -NoNewline "`n🤖 Fetching Node Conditions..." -ForegroundColor Yellow # Fetch nodes $nodes = kubectl get nodes -o json | ConvertFrom-Json $totalNodes = $nodes.items.Count if ($totalNodes -eq 0) { Write-Host "`r🤖 ❌ No nodes found." -ForegroundColor Red if (-not $Global:MakeReport -and -not $Html) { Read-Host "🤖 Press Enter to return to the menu" } return } Write-Host "`r🤖 ✅ Nodes fetched. (Total: $totalNodes)" -ForegroundColor Green # **Track total Not Ready nodes across the cluster** $totalNotReadyNodes = 0 $allNodesData = @() foreach ($node in $nodes.items) { $name = $node.metadata.name $conditions = $node.status.conditions $readyCondition = $conditions | Where-Object { $_.type -eq "Ready" } $issueConditions = $conditions | Where-Object { $_.type -ne "Ready" -and $_.status -ne "False" } if ($readyCondition -and $readyCondition.status -eq "True") { $status = "✅ Healthy" $issues = "None" } else { $status = "❌ Not Ready" $totalNotReadyNodes++ $issues = if ($issueConditions) { ($issueConditions | ForEach-Object { "$($_.type): $($_.message)" }) -join " | " } else { "Unknown Issue" } } $allNodesData += [PSCustomObject]@{ Node = $name Status = $status Issues = $issues } } # If the -Html switch is used, return an HTML table if ($Html) { # Sort so that "❌ Not Ready" is at the top $sortedData = $allNodesData | Sort-Object { if ($_.Status -eq "❌ Not Ready") { 0 } else { 1 } } # Convert the sorted data to an HTML table $htmlTable = $sortedData | ConvertTo-Html -Fragment -Property Node, Status, Issues | Out-String # Insert a note about total not ready $htmlTable = "<p><strong>⚠️ Total Not Ready Nodes:</strong> $totalNotReadyNodes</p>" + $htmlTable # Return the HTML snippet (no ASCII output) return $htmlTable } if ($Global:MakeReport) { Write-ToReport "`n[🌍 Node Conditions]" Write-ToReport "`n⚠️ Total Not Ready Nodes in the Cluster: $totalNotReadyNodes" Write-ToReport "-----------------------------------------------------------" # Sort nodes: Critical first, then Warning, then Normal $sortedNodes = $allNodesData | Sort-Object { if ($_.Status -eq "❌ Not Ready") { 1 } elseif ($_.Status -eq "⚠️ Unknown") { 2 } else { 3 } } # Format as a table and write to report $tableString = $sortedNodes | Format-Table -Property Node, Status, Issues -AutoSize | Out-String Write-ToReport $tableString return } # **Pagination Setup** $currentPage = 0 $totalPages = [math]::Ceiling($totalNodes / $PageSize) do { Clear-Host Write-Host "`n[🌍 Node Conditions - Page $($currentPage + 1) of $totalPages]" -ForegroundColor Cyan # **Display total 'Not Ready' nodes in the speech bubble before pagination starts** $msg = @( "🤖 Nodes are assessed for readiness and issues.", "", " If a node is 'Not Ready', it may impact workloads.", "", "📌 Common Causes of 'Not Ready':", " - Network issues preventing API communication", " - Insufficient CPU/Memory on the node", " - Disk pressure or PID pressure detected", " - Node failing to join due to missing CNI plugins", "", "🔍 Troubleshooting Tips:", " - Run: kubectl describe node <NODE_NAME>", " - Check kubelet logs: journalctl -u kubelet -f", " - Verify networking: kubectl get pods -A -o wide", "", "⚠️ Total Not Ready Nodes in the Cluster: $totalNotReadyNodes" ) # Show speech bubble only on the first page if ($currentPage -eq 0) { Write-SpeechBubble -msg $msg -color "Cyan" -icon "🤖" -lastColor "Red" -delay 50 # first page only } # Display current page $startIndex = $currentPage * $PageSize $endIndex = [math]::Min($startIndex + $PageSize, $totalNodes) $tableData = $allNodesData[$startIndex..($endIndex - 1)] if ($tableData) { $tableData | Format-Table -AutoSize } # Call the pagination function $newPage = Show-Pagination -currentPage $currentPage -totalPages $totalPages # Exit pagination if 'C' (Continue) was selected if ($newPage -eq -1) { break } $currentPage = $newPage } while ($true) } function Show-NodeResourceUsage { param( [int]$PageSize = 10, # Number of nodes per page [switch]$Html # If specified, return an HTML table (no ASCII pagination) ) if (-not $Global:MakeReport -and -not $Html) { Clear-Host } Write-Host "`n[📊 Node Resource Usage]" -ForegroundColor Cyan if (-not $Global:MakeReport -and -not $Html) { Write-Host -NoNewline "`n🤖 Fetching Node Data & Resource Usage..." -ForegroundColor Yellow } # Get thresholds and node data if (-not $Global:MakeReport -and -not $Html) { $thresholds = Get-KubeBuddyThresholds } else { $thresholds = Get-KubeBuddyThresholds -Silent } $allocatableRaw = kubectl get nodes -o json | ConvertFrom-Json $nodeUsageRaw = kubectl top nodes --no-headers $totalNodes = $allocatableRaw.items.Count if ($totalNodes -eq 0) { Write-Host "`r🤖 ❌ No nodes found in the cluster." -ForegroundColor Red if (-not $Global:MakeReport -and -not $Html) { Read-Host "🤖 Press Enter to return to the menu" } return } Write-Host "`r🤖 ✅ Nodes fetched. (Total: $totalNodes)" -ForegroundColor Green # Track total warnings across all nodes $totalWarnings = 0 $allNodesData = @() # Preprocess all nodes to count warnings foreach ($node in $allocatableRaw.items) { $nodeName = $node.metadata.name $allocatableCPU = [int]($node.status.allocatable.cpu -replace "m", "") $allocatableMem = [math]::Round(([int]($node.status.allocatable.memory -replace "Ki", "")) / 1024) $nodeStats = $nodeUsageRaw | Where-Object { $_ -match "^$nodeName\s" } if ($nodeStats) { $values = $nodeStats -split "\s+" $usedCPU = if ($values[1] -match "^\d+m?$") { [int]($values[1] -replace "m", "") } else { 0 } $usedMem = if ($values[3] -match "^\d+Mi?$") { [math]::Round([int]($values[3] -replace "Mi", "")) } else { 0 } $cpuUsagePercent = [math]::Round(($usedCPU / $allocatableCPU) * 100, 2) $memUsagePercent = [math]::Round(($usedMem / $allocatableMem) * 100, 2) # CPU alert $cpuAlert = if ($cpuUsagePercent -gt $thresholds.cpu_critical) { "🔴 Critical"; $totalWarnings++ } elseif ($cpuUsagePercent -gt $thresholds.cpu_warning) { "🟡 Warning"; $totalWarnings++ } else { "✅ Normal" } # Memory alert $memAlert = if ($memUsagePercent -gt $thresholds.mem_critical) { "🔴 Critical"; $totalWarnings++ } elseif ($memUsagePercent -gt $thresholds.mem_warning) { "🟡 Warning"; $totalWarnings++ } else { "✅ Normal" } # Disk usage check $diskUsagePercent = "<unknown>" $diskStatus = "⚠️ Unknown" if ($values.Length -ge 5 -and $values[4] -match "^\d+%$") { $diskUsagePercent = [int]($values[4] -replace "%", "") $diskStatus = if ($diskUsagePercent -gt 80) { "🔴 Critical"; $totalWarnings++ } elseif ($diskUsagePercent -gt 60) { "🟡 Warning"; $totalWarnings++ } else { "✅ Normal" } } # Store node data $allNodesData += [PSCustomObject]@{ Node = $nodeName "CPU %" = "$cpuUsagePercent%" "CPU Used" = "$usedCPU mC" "CPU Total" = "$allocatableCPU mC" "CPU Status" = $cpuAlert "Mem %" = "$memUsagePercent%" "Mem Used" = "$usedMem Mi" "Mem Total" = "$allocatableMem Mi" "Mem Status" = $memAlert "Disk %" = if ($diskUsagePercent -eq "<unknown>") { "⚠️ Unknown" } else { "$diskUsagePercent%" } "Disk Status" = $diskStatus } } } # If in report mode (MakeReport) or no HTML switch, do normal ASCII printing if ($Global:MakeReport -and -not $Html) { Write-ToReport "`n[📊 Node Resource Usage]" Write-ToReport "`n⚠️ Total Resource Warnings Across All Nodes: $totalWarnings" Write-ToReport "--------------------------------------------------------------------------" # Sort nodes: Crit first, then Warning/Unknown, then Normal $sortedNodes = $allNodesData | Sort-Object { if ($_.‘CPU Status’ -eq "🔴 Critical" -or $_.‘Mem Status’ -eq "🔴 Critical" -or $_.‘Disk Status’ -eq "⚠️ Unknown") { 1 } elseif ($_.‘CPU Status’ -eq "🟡 Warning" -or $_.‘Mem Status’ -eq "🟡 Warning" -or $_.‘Disk Status’ -eq "🟡 Warning") { 2 } else { 3 } } # ASCII table $tableString = $sortedNodes | Format-Table -Property Node, "CPU Status", "CPU %", "CPU Used", "CPU Total", "Mem Status", "Mem %", "Mem Used", "Mem Total", "Disk %", "Disk Status" -AutoSize | Out-String Write-ToReport $tableString return } # If the -Html switch is specified, return an HTML table if ($Html) { # Sort the data the same way: critical -> warning -> normal $sortedHtmlData = $allNodesData | Sort-Object { if ($_.‘CPU Status’ -eq "🔴 Critical" -or $_.‘Mem Status’ -eq "🔴 Critical" -or $_.‘Disk Status’ -eq "⚠️ Unknown") { 1 } elseif ($_.‘CPU Status’ -eq "🟡 Warning" -or $_.‘Mem Status’ -eq "🟡 Warning" -or $_.‘Disk Status’ -eq "🟡 Warning") { 2 } else { 3 } } # Convert to a real HTML table # We'll show columns in a certain order, e.g.: Node, CPU Status, CPU %, CPU Used, CPU Total, ... $columns = "Node", "CPU Status", "CPU %", "CPU Used", "CPU Total", "Mem Status", "Mem %", "Mem Used", "Mem Total", "Disk %", "Disk Status" $htmlTable = $sortedHtmlData | ConvertTo-Html -Fragment -Property $columns -PreContent "<h2>Node Resource Usage</h2>" | Out-String # Insert a note about total warnings $htmlTable = "<p><strong>⚠️ Total Resource Warnings Across All Nodes:</strong> $totalWarnings</p>" + $htmlTable return $htmlTable } # Otherwise, do console pagination # (If not in MakeReport mode and no HTML switch) $currentPage = 0 $totalPages = [math]::Ceiling($totalNodes / $PageSize) do { Clear-Host Write-Host "`n[📊 Node Resource Usage - Page $($currentPage + 1) of $totalPages]" -ForegroundColor Cyan $msg = @( "🤖 Nodes are assessed for CPU, memory, and disk usage. Alerts indicate high resource utilization.", "", "📌 If CPU or memory usage is high, check workloads consuming excessive resources and optimize them.", "📌 If disk usage is critical, consider adding storage capacity or cleaning up unused data.", "", "⚠️ Total Resource Warnings Across All Nodes: $totalWarnings" ) if ($currentPage -eq 0) { Write-SpeechBubble -msg $msg -color "Cyan" -icon "🤖" -lastColor "Red" -delay 50 # first page only } # Pagination $startIndex = $currentPage * $PageSize $endIndex = [math]::Min($startIndex + $PageSize, $totalNodes) $tableData = $allNodesData[$startIndex..($endIndex - 1)] if ($tableData) { $tableData | Format-Table -Property Node, "CPU %", "CPU Used", "CPU Total", "CPU Status", "Mem %", "Mem Used", "Mem Total", "Mem Status", "Disk %", "Disk Status" -AutoSize } $newPage = Show-Pagination -currentPage $currentPage -totalPages $totalPages if ($newPage -eq -1) { break } $currentPage = $newPage } while ($true) } |