Private/jobs-functions.ps1
function Show-StuckJobs { param( [int]$PageSize = 10, [switch]$Html ) if (-not $Global:MakeReport -and -not $Html) { Clear-Host } Write-Host "`n[ā³ Stuck Kubernetes Jobs]" -ForegroundColor Cyan Write-Host -NoNewline "`nš¤ Fetching Job Data..." -ForegroundColor Yellow # Fetch jobs $kubectlOutput = kubectl get jobs --all-namespaces -o json 2>&1 | Out-String if (-not $Global:MakeReport -and -not $Html) { $thresholds = Get-KubeBuddyThresholds } else { $thresholds = Get-KubeBuddyThresholds -Silent } # Check for errors if ($kubectlOutput -match "error|not found|forbidden") { Write-Host "`rš¤ ā Error retrieving job data: $kubectlOutput" -ForegroundColor Red if ($Global:MakeReport -and -not $Html) { Write-ToReport "`n[ā³ Stuck Kubernetes Jobs]`n" Write-ToReport "ā Error retrieving job data: $kubectlOutput" } if (-not $Global:MakeReport -and -not $Html) { Read-Host "š¤ Press Enter to return to the menu" } if ($Html) { return "<p><strong>ā Error retrieving job data: $kubectlOutput</strong></p>" } return } if ($kubectlOutput -match "^{") { $jobs = $kubectlOutput | ConvertFrom-Json | Select-Object -ExpandProperty items } else { Write-Host "`rš¤ ā Unexpected response from kubectl. No valid JSON received." -ForegroundColor Red if ($Global:MakeReport -and -not $Html) { Write-ToReport "`n[ā³ Stuck Kubernetes Jobs]`n" Write-ToReport "ā Unexpected response from kubectl. No valid JSON received." } if (-not $Global:MakeReport -and -not $Html) { Read-Host "š¤ Press Enter to return to the menu" } if ($Html) { return "<p><strong>ā Unexpected response from kubectl. No valid JSON received.</strong></p>" } return } if (-not $jobs -or $jobs.Count -eq 0) { Write-Host "`rš¤ ā No jobs found in the cluster." -ForegroundColor Green if ($Global:MakeReport -and -not $Html) { Write-ToReport "`n[ā³ Stuck Kubernetes Jobs]`n" Write-ToReport "ā No jobs found in the cluster." } if (-not $Global:MakeReport -and -not $Html) { Read-Host "š¤ Press Enter to return to the menu" } if ($Html) { return "<p><strong>ā No jobs found in the cluster.</strong></p>" } return } Write-Host "`rš¤ ā Jobs fetched. (Total: $($jobs.Count))" -ForegroundColor Green Write-Host -NoNewline "`nš¤ Analyzing Stuck Jobs..." -ForegroundColor Yellow # Filter stuck jobs $stuckJobs = $jobs | Where-Object { (-not $_.status.conditions -or $_.status.conditions.type -notcontains "Complete") -and # Not marked complete $_.status.PSObject.Properties['active'] -and $_.status.active -gt 0 -and # Has active pods (-not $_.status.PSObject.Properties['ready'] -or $_.status.ready -eq 0) -and # No ready pods (-not $_.status.PSObject.Properties['succeeded'] -or $_.status.succeeded -eq 0) -and # Not succeeded (-not $_.status.PSObject.Properties['failed'] -or $_.status.failed -eq 0) -and # Not failed $_.status.PSObject.Properties['startTime'] -and # Has a startTime ((New-TimeSpan -Start $_.status.startTime -End (Get-Date)).TotalHours -gt $thresholds.stuck_job_hours) } if (-not $stuckJobs -or $stuckJobs.Count -eq 0) { Write-Host "`rš¤ ā No stuck jobs found." -ForegroundColor Green if ($Global:MakeReport -and -not $Html) { Write-ToReport "`n[ā³ Stuck Kubernetes Jobs]`n" Write-ToReport "ā No stuck jobs found." } if (-not $Global:MakeReport -and -not $Html) { Read-Host "š¤ Press Enter to return to the menu" } if ($Html) { return "<p><strong>ā No stuck jobs found.</strong></p>" } return } Write-Host "`rš¤ ā Job analysis complete. ($($stuckJobs.Count) stuck jobs detected)" -ForegroundColor Green # If -Html is specified, return an HTML table if ($Html) { # Build PSCustomObject array $tableData = foreach ($job in $stuckJobs) { $ns = $job.metadata.namespace $jobName = $job.metadata.name $ageHours = ((New-TimeSpan -Start $job.status.startTime -End (Get-Date)).TotalHours) -as [int] [PSCustomObject]@{ Namespace = $ns Job = $jobName Age_Hours = $ageHours Status = "š” Stuck" } } # Convert to HTML $htmlTable = $tableData | ConvertTo-Html -Fragment -Property Namespace, Job, Age_Hours, Status | Out-String # Insert note about total $htmlTable = "<p><strong>ā ļø Total Stuck Jobs Found:</strong> $($stuckJobs.Count)</p>" + $htmlTable return $htmlTable } # If in report mode (no -Html), do original ASCII approach if ($Global:MakeReport) { Write-ToReport "`n[ā³ Stuck Kubernetes Jobs]`n" Write-ToReport "ā ļø Total Stuck Jobs Found: $($stuckJobs.Count)" Write-ToReport "---------------------------------------------" $tableData = @() foreach ($job in $stuckJobs) { $ns = $job.metadata.namespace $jobName = $job.metadata.name $ageHours = ((New-TimeSpan -Start $job.status.startTime -End (Get-Date)).TotalHours) -as [int] $tableData += [PSCustomObject]@{ Namespace = $ns Job = $jobName Age_Hours = $ageHours Status = "š” Stuck" } } $tableString = $tableData | Format-Table Namespace, Job, Age_Hours, Status -AutoSize | Out-String Write-ToReport $tableString return } # Otherwise, console pagination $totalJobs = $stuckJobs.Count $currentPage = 0 $totalPages = [math]::Ceiling($totalJobs / $PageSize) do { Clear-Host Write-Host "`n[ā³ Stuck Kubernetes Jobs - Page $($currentPage + 1) of $totalPages]" -ForegroundColor Cyan $msg = @( "š¤ Kubernetes Jobs should complete within a reasonable time.", "", "š This check identifies jobs that have been running too long and have not completed, failed, or succeeded.", "š Possible causes:", " - Stuck pods or unresponsive workloads", " - Misconfigured restart policies", " - Insufficient resources (CPU/Memory)", "", "ā ļø Investigate these jobs to determine the cause and resolve issues.", "", "ā ļø Total Stuck Jobs Found: $($stuckJobs.Count)" ) if ($currentPage -eq 0) { Write-SpeechBubble -msg $msg -color "Cyan" -icon "š¤" -lastColor "Red" -delay 50 # first page only } $startIndex = $currentPage * $PageSize $endIndex = [math]::Min($startIndex + $PageSize, $totalJobs) $tableData = @() for ($i = $startIndex; $i -lt $endIndex; $i++) { $job = $stuckJobs[$i] $tableData += [PSCustomObject]@{ Namespace = $job.metadata.namespace Job = $job.metadata.name Age_Hours = ((New-TimeSpan -Start $job.status.startTime -End (Get-Date)).TotalHours) -as [int] Status = "š” Stuck" } } if ($tableData) { $tableData | Format-Table Namespace, Job, Age_Hours, Status -AutoSize } $newPage = Show-Pagination -currentPage $currentPage -totalPages $totalPages if ($newPage -eq -1) { break } $currentPage = $newPage } while ($true) } function Show-FailedJobs { param( [int]$PageSize = 10, [switch]$Html ) if (-not $Global:MakeReport -and -not $Html) { Clear-Host } Write-Host "`n[š“ Failed Kubernetes Jobs]" -ForegroundColor Cyan Write-Host -NoNewline "`nš¤ Fetching Job Data..." -ForegroundColor Yellow # Fetch jobs $kubectlOutput = kubectl get jobs --all-namespaces -o json 2>&1 | Out-String if (-not $Global:MakeReport -and -not $Html) { $thresholds = Get-KubeBuddyThresholds } else { $thresholds = Get-KubeBuddyThresholds -Silent } # Check for errors if ($kubectlOutput -match "error|not found|forbidden") { Write-Host "`rš¤ ā Error retrieving job data: $kubectlOutput" -ForegroundColor Red if ($Global:MakeReport -and -not $Html) { Write-ToReport "`n[š“ Failed Kubernetes Jobs]`n" Write-ToReport "ā Error retrieving job data: $kubectlOutput" } if (-not $Global:MakeReport -and -not $Html) { Read-Host "š¤ Press Enter to return to the menu" } if ($Html) { return "<p><strong>ā Error retrieving job data: $kubectlOutput</strong></p>" } return } if ($kubectlOutput -match "^{") { $jobs = $kubectlOutput | ConvertFrom-Json | Select-Object -ExpandProperty items } else { Write-Host "`rš¤ ā Unexpected response from kubectl. No valid JSON received." -ForegroundColor Red if ($Global:MakeReport -and -not $Html) { Write-ToReport "`n[š“ Failed Kubernetes Jobs]`n" Write-ToReport "ā Unexpected response from kubectl. No valid JSON received." } if (-not $Global:MakeReport -and -not $Html) { Read-Host "š¤ Press Enter to return to the menu" } if ($Html) { return "<p><strong>ā Unexpected response from kubectl. No valid JSON received.</strong></p>" } return } if (-not $jobs -or $jobs.Count -eq 0) { Write-Host "`rš¤ ā No jobs found in the cluster." -ForegroundColor Green if ($Global:MakeReport -and -not $Html) { Write-ToReport "`n[š“ Failed Kubernetes Jobs]`n" Write-ToReport "ā No jobs found in the cluster." } if (-not $Global:MakeReport -and -not $Html) { Read-Host "š¤ Press Enter to return to the menu" } if ($Html) { return "<p><strong>ā No failed jobs found.</strong></p>" } return } Write-Host "`rš¤ ā Jobs fetched. (Total: $($jobs.Count))" -ForegroundColor Green Write-Host -NoNewline "`nš¤ Analyzing Failed Jobs..." -ForegroundColor Yellow # Filter failed jobs $failedJobs = $jobs | Where-Object { $_.status.PSObject.Properties['failed'] -and $_.status.failed -gt 0 -and # Job has failed (-not $_.status.PSObject.Properties['succeeded'] -or $_.status.succeeded -eq 0) -and # Not succeeded $_.status.PSObject.Properties['startTime'] -and ((New-TimeSpan -Start $_.status.startTime -End (Get-Date)).TotalHours -gt $thresholds.failed_job_hours) } if (-not $failedJobs -or $failedJobs.Count -eq 0) { Write-Host "`rš¤ ā No failed jobs found." -ForegroundColor Green if ($Global:MakeReport -and -not $Html) { Write-ToReport "`n[š“ Failed Kubernetes Jobs]`n" Write-ToReport "ā No failed jobs found." } if (-not $Global:MakeReport -and -not $Html) { Read-Host "š¤ Press Enter to return to the menu" } if ($Html) { return "<p><strong>ā No failed jobs found.</strong></p>" } return } Write-Host "`rš¤ ā Job analysis complete. ($($failedJobs.Count) failed jobs detected)" -ForegroundColor Green # If -Html is specified, return an HTML table if ($Html) { $tableData = foreach ($job in $failedJobs) { [PSCustomObject]@{ Namespace = $job.metadata.namespace Job = $job.metadata.name Age_Hours = ((New-TimeSpan -Start $job.status.startTime -End (Get-Date)).TotalHours) -as [int] Failures = if ($job.status.PSObject.Properties['failed']) { $job.status.failed } else { "Unknown" } Status = "š“ Failed" } } # Convert to HTML $htmlTable = $tableData | ConvertTo-Html -Fragment -Property Namespace, Job, Age_Hours, Failures, Status -PreContent "<h2>Failed Kubernetes Jobs</h2>" | Out-String # Insert note about total $htmlTable = "<p><strong>ā ļø Total Failed Jobs Found:</strong> $($failedJobs.Count)</p>" + $htmlTable return $htmlTable } # If in report mode (no -Html), do original ASCII approach if ($Global:MakeReport) { Write-ToReport "`n[š“ Failed Kubernetes Jobs]`n" Write-ToReport "ā ļø Total Failed Jobs Found: $($failedJobs.Count)" Write-ToReport "---------------------------------------------" $tableData = @() foreach ($job in $failedJobs) { $ns = $job.metadata.namespace $jobName = $job.metadata.name $ageHours = ((New-TimeSpan -Start $job.status.startTime -End (Get-Date)).TotalHours) -as [int] $failCount = if ($job.status.PSObject.Properties['failed']) { $job.status.failed } else { "Unknown" } $tableData += [PSCustomObject]@{ Namespace = $ns Job = $jobName Age_Hours = $ageHours Failures = $failCount Status = "š“ Failed" } } $tableString = $tableData | Format-Table Namespace, Job, Age_Hours, Failures, Status -AutoSize | Out-String Write-ToReport $tableString return } # Otherwise, console pagination $totalJobs = $failedJobs.Count $currentPage = 0 $totalPages = [math]::Ceiling($totalJobs / $PageSize) do { Clear-Host Write-Host "`n[š“ Failed Kubernetes Jobs - Page $($currentPage + 1) of $totalPages]" -ForegroundColor Cyan $msg = @( "š¤ Kubernetes Jobs should complete successfully.", "", "š This check identifies jobs that have encountered failures.", " - Jobs may fail due to insufficient resources, timeouts, or misconfigurations.", " - Review logs with 'kubectl logs job/<job-name>'", " - Investigate pod failures with 'kubectl describe job/<job-name>'", "", "ā ļø Consider re-running or debugging these jobs for resolution.", "", "ā ļø Total Failed Jobs Found: $($failedJobs.Count)" ) if ($currentPage -eq 0) { Write-SpeechBubble -msg $msg -color "Cyan" -icon "š¤" -lastColor "Red" -delay 50 # first page only } $startIndex = $currentPage * $totalJobs / $PageSize $startIndex = $currentPage * $PageSize $endIndex = [math]::Min($startIndex + $PageSize, $totalJobs) $tableData = @() for ($i = $startIndex; $i -lt $endIndex; $i++) { $job = $failedJobs[$i] $tableData += [PSCustomObject]@{ Namespace = $job.metadata.namespace Job = $job.metadata.name Age_Hours = ((New-TimeSpan -Start $job.status.startTime -End (Get-Date)).TotalHours) -as [int] Failures = if ($job.status.PSObject.Properties['failed']) { $job.status.failed } else { "Unknown" } Status = "š“ Failed" } } if ($tableData) { $tableData | Format-Table Namespace, Job, Age_Hours, Failures, Status -AutoSize } $newPage = Show-Pagination -currentPage $currentPage -totalPages $totalPages if ($newPage -eq -1) { break } $currentPage = $newPage } while ($true) } |