Public/kubebuddy.ps1
|
$script:KubeBuddyModuleVersion = "v0.0.28" function Get-KubeBuddyRuntimeRid { $os = if ($IsWindows) { "windows" } elseif ($IsMacOS) { "darwin" } elseif ($IsLinux) { "linux" } else { $null } $arch = switch ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture) { ([System.Runtime.InteropServices.Architecture]::X64) { "amd64" } ([System.Runtime.InteropServices.Architecture]::Arm64) { "arm64" } default { $null } } if ($os -and $arch) { return "$os-$arch" } return $null } function Resolve-KubeBuddyNativeCommand { $moduleRoot = Split-Path -Parent $PSScriptRoot $candidates = @() if ($env:KUBEBUDDY_BINARY) { $candidates += $env:KUBEBUDDY_BINARY } $rid = Get-KubeBuddyRuntimeRid if ($rid) { $binaryName = if ($IsWindows) { "kubebuddy.exe" } else { "kubebuddy" } $candidates += @( (Join-Path $moduleRoot "bin/$rid/$binaryName"), (Join-Path $moduleRoot "runtimes/$rid/native/$binaryName") ) } $candidates += @( (Join-Path $moduleRoot "kubebuddy"), (Join-Path $moduleRoot "kubebuddy.exe"), (Join-Path $moduleRoot "bin/kubebuddy"), (Join-Path $moduleRoot "bin/kubebuddy.exe") ) foreach ($candidate in $candidates) { if ($candidate -and (Test-Path $candidate)) { return @{ FilePath = (Resolve-Path $candidate).Path PrefixArguments = @() WorkingDirectory = $moduleRoot } } } $command = Get-Command kubebuddy -ErrorAction SilentlyContinue if ($command) { return @{ FilePath = $command.Source PrefixArguments = @() WorkingDirectory = (Get-Location).Path } } $goCommand = Get-Command go -ErrorAction SilentlyContinue $goMain = Join-Path $moduleRoot "cmd/kubebuddy/main.go" if ($goCommand -and (Test-Path $goMain)) { return @{ FilePath = $goCommand.Source PrefixArguments = @("run", (Join-Path $moduleRoot "cmd/kubebuddy")) WorkingDirectory = $moduleRoot } } throw "Unable to locate the native KubeBuddy CLI. The PowerShell module expects a bundled binary, a kubebuddy binary on PATH, an explicit KUBEBUDDY_BINARY override, or a repository checkout with Go available." } function Invoke-KubeBuddyNativeCommand { param( [string[]]$Arguments, [hashtable]$Environment = @{}, [string]$WorkingDirectory ) $command = Resolve-KubeBuddyNativeCommand $previousLocation = $null $savedEnvironment = @{} try { foreach ($entry in $Environment.GetEnumerator()) { $savedEnvironment[$entry.Key] = [Environment]::GetEnvironmentVariable($entry.Key) [Environment]::SetEnvironmentVariable($entry.Key, [string]$entry.Value) } $targetDirectory = if ($WorkingDirectory) { $WorkingDirectory } else { $command.WorkingDirectory } if ($targetDirectory) { $previousLocation = Get-Location Set-Location $targetDirectory } & $command.FilePath @($command.PrefixArguments + $Arguments) | Out-Host return [int]$LASTEXITCODE } finally { if ($previousLocation) { Set-Location $previousLocation } foreach ($entry in $savedEnvironment.GetEnumerator()) { [Environment]::SetEnvironmentVariable($entry.Key, $entry.Value) } } } function Move-KubeBuddyGeneratedReports { param( [string]$OutputDirectory, [string]$BaseName, [string[]]$Extensions ) if (-not (Test-Path $OutputDirectory)) { return } foreach ($extension in $Extensions) { $latest = Get-ChildItem -Path $OutputDirectory -Filter "kubebuddy-report-*.$extension" -File -ErrorAction SilentlyContinue | Sort-Object LastWriteTimeUtc -Descending | Select-Object -First 1 if (-not $latest) { continue } $target = Join-Path $OutputDirectory "$BaseName.$extension" if ($latest.FullName -ne $target) { Move-Item -Path $latest.FullName -Destination $target -Force } } } function Invoke-KubeBuddy { [CmdletBinding()] param ( [switch]$Tui, [switch]$Guided, [switch]$Menu, [switch]$HtmlReport, [switch]$txtReport, [switch]$jsonReport, [switch]$CsvReport, [switch]$Aks, [switch]$ExcludeNamespaces, [string[]]$AdditionalExcludedNamespaces, [switch]$yes, [string]$SubscriptionId, [string]$ResourceGroup, [string]$ClusterName, [string]$outputpath, [switch]$UseAksRestApi, [string]$ConfigPath, [switch]$IncludePrometheus, [string]$PrometheusUrl, [string]$PrometheusMode, [string]$PrometheusBearerTokenEnv, [System.Management.Automation.PSCredential]$PrometheusCredential, [switch]$RadarUpload, [switch]$RadarCompare, [switch]$RadarFetchConfig, [string]$RadarConfigId, [string]$RadarApiBaseUrl, [string]$RadarEnvironment, [string]$RadarApiUserEnv, [string]$RadarApiSecretEnv ) $interactiveModes = @($Tui, $Guided, $Menu) | Where-Object { $_ } if ($interactiveModes.Count -gt 1) { throw "Use only one interactive mode switch: -Tui, -Guided, or -Menu." } if ($Tui -or $Guided -or $Menu) { $interactiveArgs = @() if ($Tui) { $interactiveArgs = @("tui") } elseif ($Guided) { $interactiveArgs = @("guided") } else { $interactiveArgs = @("menu") } if ($ConfigPath) { $interactiveArgs += @("--config-path", $ConfigPath) } if ($ExcludeNamespaces) { $interactiveArgs += "--exclude-namespaces" } if ($SubscriptionId) { $interactiveArgs += @("--subscription-id", $SubscriptionId) } if ($ResourceGroup) { $interactiveArgs += @("--resource-group", $ResourceGroup) } if ($ClusterName) { $interactiveArgs += @("--cluster-name", $ClusterName) } $exitCode = Invoke-KubeBuddyNativeCommand -Arguments $interactiveArgs -WorkingDirectory (Get-Location).Path if ($exitCode -ne 0) { throw "Native KubeBuddy CLI exited with code $exitCode." } return } if (-not ($HtmlReport -or $txtReport -or $jsonReport -or $CsvReport)) { $HtmlReport = $true } $extensions = @() if ($HtmlReport) { $extensions += "html" } if ($txtReport) { $extensions += "txt" } if ($jsonReport) { $extensions += "json" } if ($CsvReport) { $extensions += "csv" } $requestedOutputPath = $outputpath if (-not $requestedOutputPath) { $requestedOutputPath = Join-Path -Path $HOME -ChildPath "kubebuddy-report" } $reportDirectory = $requestedOutputPath $reportBaseName = $null $outputExtension = [IO.Path]::GetExtension($requestedOutputPath) if ($outputExtension) { $reportDirectory = Split-Path -Parent $requestedOutputPath if (-not $reportDirectory) { $reportDirectory = (Get-Location).Path } $reportBaseName = [IO.Path]::GetFileNameWithoutExtension($requestedOutputPath) } if (-not (Test-Path $reportDirectory)) { New-Item -ItemType Directory -Path $reportDirectory -Force | Out-Null } $arguments = @("run") if ($HtmlReport) { $arguments += "--html-report" } if ($txtReport) { $arguments += "--txt-report" } if ($jsonReport) { $arguments += "--json-report" } if ($CsvReport) { $arguments += "--csv-report" } if ($Aks) { $arguments += "--aks" } if ($ExcludeNamespaces) { $arguments += "--exclude-namespaces" } if ($yes) { $arguments += "--yes" } if ($UseAksRestApi) { $arguments += "--use-aks-rest-api" } if ($IncludePrometheus) { $arguments += "--include-prometheus" } if ($RadarUpload) { $arguments += "--radar-upload" } if ($RadarCompare) { $arguments += "--radar-compare" } if ($RadarFetchConfig) { $arguments += "--radar-fetch-config" } if ($SubscriptionId) { $arguments += @("--subscription-id", $SubscriptionId) } if ($ResourceGroup) { $arguments += @("--resource-group", $ResourceGroup) } if ($ClusterName) { $arguments += @("--cluster-name", $ClusterName) } if ($ConfigPath) { $arguments += @("--config-path", $ConfigPath) } if ($PrometheusUrl) { $arguments += @("--prometheus-url", $PrometheusUrl) } if ($PrometheusMode) { $arguments += @("--prometheus-mode", $PrometheusMode) } if ($PrometheusBearerTokenEnv) { $arguments += @("--prometheus-bearer-token-env", $PrometheusBearerTokenEnv) } if ($RadarConfigId) { $arguments += @("--radar-config-id", $RadarConfigId) } if ($RadarApiBaseUrl) { $arguments += @("--radar-api-base-url", $RadarApiBaseUrl) } if ($RadarEnvironment) { $arguments += @("--radar-environment", $RadarEnvironment) } if ($RadarApiUserEnv) { $arguments += @("--radar-api-user-env", $RadarApiUserEnv) } if ($RadarApiSecretEnv) { $arguments += @("--radar-api-secret-env", $RadarApiSecretEnv) } foreach ($namespace in @($AdditionalExcludedNamespaces)) { if ($namespace) { $arguments += @("--additional-excluded-namespaces", $namespace) } } $arguments += @("--output-path", $reportDirectory) $environment = @{} if ($PrometheusCredential) { $environment["PROMETHEUS_USERNAME"] = $PrometheusCredential.UserName $environment["PROMETHEUS_PASSWORD"] = $PrometheusCredential.GetNetworkCredential().Password if (-not $PrometheusMode) { $arguments += @("--prometheus-mode", "basic") } } $exitCode = Invoke-KubeBuddyNativeCommand -Arguments $arguments -Environment $environment -WorkingDirectory (Get-Location).Path if ($exitCode -ne 0) { throw "Native KubeBuddy CLI exited with code $exitCode." } if ($reportBaseName) { Move-KubeBuddyGeneratedReports -OutputDirectory $reportDirectory -BaseName $reportBaseName -Extensions $extensions } } |