Private/configmaps-functions.ps1
function Check-OrphanedConfigMaps { param( [int]$PageSize = 10, [switch]$Html, [switch]$ExcludeNamespaces, [switch]$Json, [object]$KubeData ) if (-not $Global:MakeReport -and -not $Html -and -not $Json) { Clear-Host } Write-Host "`n[📜 Orphaned ConfigMaps]" -ForegroundColor Cyan Write-Host -NoNewline "`n🤖 Fetching ConfigMaps..." -ForegroundColor Yellow $excludedConfigMapPatterns = @( "^sh\.helm\.release\.v1\.", "^kube-root-ca\.crt$" ) try { $configMaps = if ($KubeData -and $KubeData.ConfigMaps) { $KubeData.ConfigMaps } else { kubectl get configmaps --all-namespaces -o json | ConvertFrom-Json | Select-Object -ExpandProperty items } } catch { Write-Host "`r🤖 ❌ Failed to fetch ConfigMaps: $_" -ForegroundColor Red return } $configMaps = $configMaps | Where-Object { $_.metadata.name -notmatch ($excludedConfigMapPatterns -join "|") } if ($ExcludeNamespaces) { $configMaps = Exclude-Namespaces -items $configMaps } Write-Host "`r🤖 ✅ ConfigMaps fetched. ($($configMaps.Count) total)" -ForegroundColor Green Write-Host -NoNewline "`n🤖 Checking ConfigMap usage..." -ForegroundColor Yellow $usedConfigMaps = [System.Collections.Generic.HashSet[string]]::new() $pods = if ($KubeData -and $KubeData.Pods) { $KubeData.Pods.items } else { kubectl get pods --all-namespaces -o json | ConvertFrom-Json | Select-Object -ExpandProperty items } $workloadTypes = @("deployments", "statefulsets", "daemonsets", "cronjobs", "jobs", "replicasets") $workloads = $workloadTypes | ForEach-Object { if ($KubeData -and $KubeData[$_]) { $KubeData[$_].items } else { kubectl get $_ --all-namespaces -o json 2>$null | ConvertFrom-Json | Select-Object -ExpandProperty items } } foreach ($resource in $pods + $workloads) { $resource.spec.volumes | Where-Object { $_.configMap } | ForEach-Object { $null = $usedConfigMaps.Add($_.configMap.name) } $containers = @() $containers += $resource.spec.containers $containers += $resource.spec.initContainers $containers += $resource.spec.ephemeralContainers foreach ($container in $containers) { $container.env | Where-Object { $_.valueFrom.configMapKeyRef } | ForEach-Object { $null = $usedConfigMaps.Add($_.valueFrom.configMapKeyRef.name) } $container.envFrom | Where-Object { $_.configMapRef } | ForEach-Object { $null = $usedConfigMaps.Add($_.configMapRef.name) } } } # Add references from annotations (ingresses, services) foreach ($annotationSet in @($KubeData.Ingresses, $KubeData.Services)) { $annotationSet | ForEach-Object { $_.metadata.annotations.Values | Where-Object { $_ -match "configMap" } | ForEach-Object { $null = $usedConfigMaps.Add($_) } } } # Add references from CR annotations if ($KubeData -and $KubeData.CRDs -and $KubeData.CustomResourcesByKind) { foreach ($kind in $KubeData.CustomResourcesByKind.Keys) { $resources = $KubeData.CustomResourcesByKind[$kind] foreach ($res in $resources) { $annotations = $res.metadata.annotations if ($annotations -is [hashtable]) { $annotations.Values | Where-Object { $_ -match "configMap" } | ForEach-Object { $null = $usedConfigMaps.Add($_) } } } } } Write-Host "`r✅ ConfigMap usage checked. " -ForegroundColor Green $orphaned = $configMaps | Where-Object { -not $usedConfigMaps.Contains($_.metadata.name) } $items = foreach ($s in $orphaned) { $ns = if ($s.metadata.namespace) { $s.metadata.namespace } else { "N/A" } $name = if ($s.metadata.name) { $s.metadata.name } else { "N/A" } [PSCustomObject]@{ Namespace = $ns Type = "📜 ConfigMap" Name = $name } } if ($items.Count -eq 0) { Write-Host "🤖 ✅ No orphaned ConfigMaps found." -ForegroundColor Green if ($Global:MakeReport -and -not $Html) { Write-ToReport "`n[📜 Orphaned ConfigMaps]`n" Write-ToReport "✅ No orphaned ConfigMaps found." } if ($Html) { return "<p><strong>✅ No orphaned ConfigMaps found.</strong></p>" } if ($Json) { return @{ Total = 0; Items = @() } } if (-not $Global:MakeReport -and -not $Html) { Read-Host "🤖 Press Enter to return to the menu" } return } if ($Json) { return @{ Total = $items.Count; Items = $items } } if ($Html) { $htmlOutput = $items | Sort-Object Namespace, Name | ConvertTo-Html -Fragment -Property Namespace, Type, Name -PreContent "<h2>Orphaned ConfigMaps</h2>" | Out-String return "<p><strong>⚠️ Total Orphaned ConfigMaps Found:</strong> $($items.Count)</p>$htmlOutput" } if ($Global:MakeReport) { Write-ToReport "`n[📜 Orphaned ConfigMaps]`n" Write-ToReport "⚠️ Total Orphaned ConfigMaps Found: $($items.Count)" $tableString = $items | Format-Table Namespace, Type, Name -AutoSize | Out-String Write-ToReport $tableString return } $total = $items.Count $currentPage = 0 $totalPages = [math]::Ceiling($total / $PageSize) do { Clear-Host Write-Host "`n[📜 Orphaned ConfigMaps - Page $($currentPage + 1) of $totalPages]" -ForegroundColor Cyan if ($currentPage -eq 0) { $msg = @( "🤖 ConfigMaps store configuration data for workloads.", "", "📌 This check identifies ConfigMaps that are not referenced by:", " - Pods, Deployments, StatefulSets, DaemonSets.", " - CronJobs, Jobs, ReplicaSets, Services, and Custom Resources.", "", "⚠️ Orphaned ConfigMaps may be outdated and can be reviewed for cleanup.", "", "⚠️ Total Orphaned ConfigMaps Found: $total" ) Write-SpeechBubble -msg $msg -color "Cyan" -icon "🤖" -lastColor "Red" -delay 50 } $paged = $items | Select-Object -Skip ($currentPage * $PageSize) -First $PageSize $paged | Format-Table Namespace, Type, Name -AutoSize | Out-Host $newPage = Show-Pagination -currentPage $currentPage -totalPages $totalPages if ($newPage -eq -1) { break } $currentPage = $newPage } while ($true) } function Check-ConfigMapDuplicates { param( [object]$KubeData, [string]$Namespace = "", [int]$PageSize = 10, [switch]$Html, [switch]$Json, [switch]$ExcludeNamespaces ) if (-not $Global:MakeReport -and -not $Html -and -not $Json) { Clear-Host } Write-Host "`n[🧬 Duplicate ConfigMap Names]" -ForegroundColor Cyan if (-not $Global:MakeReport -and -not $Html -and -not $Json) { Write-Host -NoNewline "`n🤖 Fetching ConfigMaps..." -ForegroundColor Yellow } try { $configMaps = if ($KubeData -and $KubeData.ConfigMaps) { $KubeData.ConfigMaps } else { $raw = if ($Namespace) { kubectl get configmaps -n $Namespace -o json 2>&1 } else { kubectl get configmaps --all-namespaces -o json 2>&1 } if ($raw -match "No resources found") { if ($Html) { return "<p><strong>✅ No ConfigMaps found.</strong></p>" } if ($Json) { return @{ Total = 0; Items = @() } } Write-Host "`r🤖 ✅ No ConfigMaps found." -ForegroundColor Green return } ($raw | ConvertFrom-Json).items } } catch { Write-Host "`r🤖 ❌ Error retrieving ConfigMap data: $_" -ForegroundColor Red if ($Html) { return "<p><strong>❌ Error retrieving ConfigMaps.</strong></p>" } if ($Json) { return @{ Error = "$_" } } return } if ($ExcludeNamespaces) { $configMaps = Exclude-Namespaces -items $configMaps } $results = @() $nameGroups = $configMaps | Group-Object -Property { $_.metadata.name } | Where-Object { $_.Count -gt 1 } foreach ($group in $nameGroups) { $namespaces = $group.Group | ForEach-Object { $_.metadata.namespace } $results += [PSCustomObject]@{ Name = $group.Name Namespaces = ($namespaces -join ", ") } } $total = $results.Count if ($total -eq 0) { if ($Html) { return "<p><strong>✅ No duplicate ConfigMap names found.</strong></p>" } if ($Json) { return @{ Total = 0; Items = @() } } Write-Host "`r🤖 ✅ No duplicate ConfigMap names found." -ForegroundColor Green return } Write-Host "`r🤖 ✅ Duplicate ConfigMap names found. ($total detected)" -ForegroundColor Green if ($Json) { return @{ Total = $total; Items = $results } } if ($Html) { $htmlTable = $results | Sort-Object -Property Name | ConvertTo-Html -Fragment -Property Name, Namespaces | Out-String return "<p><strong>⚠️ Total Duplicate ConfigMap Names:</strong> $total</p>" + $htmlTable } if ($Global:MakeReport) { Write-ToReport "`n[🧬 Duplicate ConfigMap Names]`n" Write-ToReport "⚠️ Total Duplicate ConfigMap Names: $total" $tableString = $results | Format-Table Name, Namespaces -AutoSize | Out-String Write-ToReport $tableString return } $currentPage = 0 $totalPages = [math]::Ceiling($total / $PageSize) do { Clear-Host Write-Host "`n[🧬 Duplicate ConfigMap Names - Page $($currentPage + 1) of $totalPages]" -ForegroundColor Cyan if ($currentPage -eq 0) { Write-SpeechBubble -msg @( "🤖 ConfigMap names reused in multiple namespaces.", "", "📌 Why this matters:", " - Can lead to confusion or unexpected overrides.", " - Often a result of copy/paste errors or lack of naming standards.", "", "⚠️ Total Duplicate Names: $total" ) -color "Cyan" -icon "🧬" -lastColor "Red" -delay 50 } $paged = $results | Select-Object -Skip ($currentPage * $PageSize) -First $PageSize if ($paged) { $paged | Format-Table Name, Namespaces -AutoSize | Out-Host } $newPage = Show-Pagination -currentPage $currentPage -totalPages $totalPages if ($newPage -eq -1) { break } $currentPage = $newPage } while ($true) } function Check-ConfigMapSize { param( [object]$KubeData, [string]$Namespace = "", [int]$PageSize = 10, [switch]$Html, [switch]$Json, [switch]$ExcludeNamespaces ) if (-not $Global:MakeReport -and -not $Html -and -not $Json) { Clear-Host } Write-Host "`n[📦 Large ConfigMaps]" -ForegroundColor Cyan if (-not $Global:MakeReport -and -not $Html -and -not $Json) { Write-Host -NoNewline "`n🤖 Fetching ConfigMaps..." -ForegroundColor Yellow } try { $configMaps = if ($KubeData -and $KubeData.ConfigMaps) { $KubeData.ConfigMaps } else { $raw = if ($Namespace) { kubectl get configmaps -n $Namespace -o json 2>&1 } else { kubectl get configmaps --all-namespaces -o json 2>&1 } if ($raw -match "No resources found") { if ($Html) { return "<p><strong>✅ No ConfigMaps found.</strong></p>" } if ($Json) { return @{ Total = 0; Items = @() } } Write-Host "`r🤖 ✅ No ConfigMaps found." -ForegroundColor Green return } ($raw | ConvertFrom-Json).items } } catch { Write-Host "`r🤖 ❌ Error retrieving ConfigMap data: $_" -ForegroundColor Red if ($Html) { return "<p><strong>❌ Error retrieving ConfigMaps.</strong></p>" } if ($Json) { return @{ Error = "$_" } } return } if ($ExcludeNamespaces) { $configMaps = Exclude-Namespaces -items $configMaps } $thresholdBytes = 1048576 $results = @() foreach ($cm in $configMaps) { $size = ($cm.data.PSObject.Properties | Measure-Object -Property Value -Sum).Sum.Length if ($size -gt $thresholdBytes) { $results += [PSCustomObject]@{ Namespace = $cm.metadata.namespace Name = $cm.metadata.name SizeBytes = $size } } } $total = $results.Count if ($total -eq 0) { if ($Html) { return "<p><strong>✅ No large ConfigMaps detected.</strong></p>" } if ($Json) { return @{ Total = 0; Items = @() } } Write-Host "`r🤖 ✅ No large ConfigMaps detected." -ForegroundColor Green return } Write-Host "`r🤖 ✅ Large ConfigMaps fetched. ($total detected)" -ForegroundColor Green if ($Json) { return @{ Total = $total; Items = $results } } if ($Html) { $htmlTable = $results | Sort-Object -Property SizeBytes -Descending | ConvertTo-Html -Fragment -Property Namespace, Name, SizeBytes | Out-String return "<p><strong>⚠️ Total Large ConfigMaps:</strong> $total</p>" + $htmlTable } if ($Global:MakeReport) { Write-ToReport "`n[📦 Large ConfigMaps]`n" Write-ToReport "⚠️ Total Large ConfigMaps: $total" $tableString = $results | Format-Table Namespace, Name, SizeBytes -AutoSize | Out-String Write-ToReport $tableString return } $currentPage = 0 $totalPages = [math]::Ceiling($total / $PageSize) do { Clear-Host Write-Host "`n[📦 Large ConfigMaps - Page $($currentPage + 1) of $totalPages]" -ForegroundColor Cyan if ($currentPage -eq 0) { Write-SpeechBubble -msg @( "🤖 ConfigMaps that exceed 1 MiB in size.", "", "📌 Why this matters:", " - Large ConfigMaps may contain sensitive or bloated data.", " - Kubernetes has size limits for ConfigMaps.", "", "⚠️ Total Large ConfigMaps: $total" ) -color "Cyan" -icon "📦" -lastColor "Red" -delay 50 } $paged = $results | Select-Object -Skip ($currentPage * $PageSize) -First $PageSize if ($paged) { $paged | Format-Table Namespace, Name, SizeBytes -AutoSize | Out-Host } $newPage = Show-Pagination -currentPage $currentPage -totalPages $totalPages if ($newPage -eq -1) { break } $currentPage = $newPage } while ($true) } |