Last active
November 3, 2021 13:05
-
-
Save queil/d4f5c3b083bdb86b326c374f8605ed07 to your computer and use it in GitHub Desktop.
posh k8s
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function k8s() { | |
$Cache = @{Names=@{}} | |
function makectx { | |
@{ | |
Namespace = "default" | |
Ctx = $(kubectl config current-context) | |
Current = @{Name = $null; TypeAlias=$null} | |
} | |
} | |
function Get-KubeNames([string]$Alias, [switch]$BusyDot = $true) { | |
if ($null -eq $Cache.Names[$Alias]) { | |
if ($BusyDot) { write-host "." -fore Cyan -NoNewLine } | |
$Cache.Names[$Alias] = Invoke-KubeCtl "get $Alias -o name" | ForEach-Object { ($_ -split '/')[1] } | |
} | |
return $Cache.Names[$Alias] | |
} | |
function rsname() { "$($script:K.Current.TypeAlias)/$($script:K.Current.Name)" } | |
class ResourceSet : System.Management.Automation.IValidateSetValuesGenerator { [string[]] GetValidValues() { return @{} }} | |
class NamespaceSet : ResourceSet { | |
[string[]] GetValidValues() { | |
if ($null -like $script:Cache.Names["ns"]) { | |
$script:Cache.Names["ns"] = Get-KubeNames "ns" | |
} | |
return $script:Cache.Names["ns"] | |
} | |
} | |
class ContextSet : System.Management.Automation.IValidateSetValuesGenerator { | |
[string[]] GetValidValues() { return $(kubectl config get-contexts -o name) } | |
} | |
function reload () { | |
param ([switch]$Hard) | |
$Namespaces = $script:Cache.Names["ns"] | |
$Namespace = $script:K.Namespace | |
$script:K = $(makectx) | |
$script:Cache = @{Names=@{}} | |
if (!$Hard) { | |
$script:Cache.Names["ns"] = $Namespaces | |
$script:K.Namespace = $Namespace | |
} | |
} | |
function Invoke-KubeCtl() { | |
if ($null -ne $script:K.Namespace) { $kargs = "-n $($script:K.Namespace) " + $args } | |
$Cmd = "kubectl $kargs" | |
if ($env:POSHK8S_SHOW_CMD) { Write-Host $Cmd -ForegroundColor Cyan } | |
Invoke-Expression $Cmd | |
} | |
function Select-KubeContext { | |
param([ValidateSet([ContextSet])][String]$Name) | |
reload -Hard | |
$script:K.Ctx = $Name | |
kubectl config use-context $Name | |
} | |
function Select-KubeNamespace { | |
param([ValidateSet([NamespaceSet])][String]$Name) | |
if ($null -like $Name) { return Get-KubeNames "ns" } | |
reload | |
$script:K.Namespace = $Name | |
} | |
function Select-KubeResource { | |
param( | |
[Parameter(Mandatory=$true, Position=0)] | |
[string]$Type, | |
[Parameter(Position=1)] | |
[ArgumentCompleter({ | |
param ( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters ) | |
$RsType = $fakeBoundParameters['Type'] | |
if ($RsType) { | |
Get-KubeNames $fakeBoundParameters['Type'] | Where-Object { $_ -like "$wordToComplete*" } | |
} | |
return @() | |
})] | |
[string]$Name | |
) | |
if ($Name -like $null) { reload; k get po; return; } | |
$script:K.Current = @{Name = $Name; TypeAlias=$Type} | |
} | |
function Get-KubeYaml { k get $(rsname) -o yaml } | |
function Get-KubeJsonPath([string]$JsonPath) { k get $(rsname) -o "jsonpath='{$($JsonPath)}'" } | |
function Get-KubeDescribeResource { k describe $(rsname) } | |
function Get-KubeLogs() { | |
[CmdletBinding()] | |
param( | |
[switch]$Follow, | |
[int]$Tail, | |
[string]$Container = $null | |
) | |
k logs $(rsname) $($Tail -gt 0 ? "--tail=$Tail" : "") $($Follow ? "--follow": "") $($Container ? "--container=$Container" : "") | |
} | |
function Delete-KubeResource() { | |
k delete $(rsname) | |
reload | |
} | |
function Restart-KubeResource() { | |
k rollout restart $(rsname) | |
w8 available | |
k get po --watch | |
reload | |
} | |
function WaitFor-KubeResource() { | |
param( | |
[Parameter(Mandatory=$true)] | |
[ValidateSet("available")] | |
$Condition | |
) | |
k wait $(rsname) --for=condition=$Condition | |
} | |
function Follow-KubeLogs | |
{ | |
param( | |
[string]$Container = $null | |
) | |
Get-KubeLogs -Tail 1 -Follow -Container:$Container | |
} | |
function Invoke-KubePodCmd() { | |
[CmdletBinding()] | |
param( | |
[string]$Cmd = "sh", | |
[string]$Container = $null | |
) | |
k exec -it $($Container ? "--container=$Container " : "")$(rsname) '--' $Cmd | |
} | |
function Invoke-KubePortForward() { | |
[CmdletBinding()] | |
param( | |
[ArgumentCompleter( { | |
param ( $CommandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameters) | |
$Target = $(rsname) | |
$PortJsonPath = switch -Regex ($Target) { | |
"^svc/.*" { "jsonpath='{.spec.ports[*].port}'" } | |
"^pod/.*" { "jsonpath='{.spec.containers[*].ports[*].containerPort}'" } | |
} | |
(k get $Target -o $PortJsonPath) -split "\s" | ? { $_ -match "^$WordToComplete.*" } | |
})] | |
[Parameter(Position=0)] | |
[Int]$RemotePort, | |
[Int]$LocalPort, | |
[switch]$Browse | |
) | |
$FinalLocalPort = $LocalPort -eq 0 ? $RemotePort -le 1024 ? $RemotePort + 8000 : $RemotePort : $LocalPort | |
if ($Browse) { x-www-browser "http://127.0.0.1:$FinalLocalPort" } | |
k port-forward $(rsname) "$($FinalLocalPort):$($RemotePort)" | |
} | |
function Prompt { | |
$arrow = "`u{e0b0}" | |
$slash = "`u{e0ba}" | |
Write-Host "λ" -NoNewline -Fore DarkBlue | |
Write-Host "`u{e0b0}" -NoNewline -Back DarkBlue -Fore Black | |
Write-Host " $($script:K.Ctx)" -NoNewline -Fore Black -Back DarkBlue | |
if ($null -eq $script:K.Namespace) { | |
Write-Host " " -Back DarkBlue -NoNewLine | |
Write-Host $arrow -Fore DarkBlue -NoNewLine | |
return " " | |
} | |
Write-Host $slash -NoNewline -Fore Green -Back DarkBlue | |
Write-Host "$($script:K.Namespace)" -Fore Black -Back Green -NoNewLine | |
if ($null -eq $script:K.Current) { | |
Write-Host " " -Back Green -NoNewLine | |
Write-Host $arrow -Fore Green -NoNewLine | |
return " " | |
} | |
Write-Host $slash -Back Green -Fore Gray -NoNewLine | |
Write-Host "$($script:K.Current.TypeAlias)" -Fore Black -Back Gray -NoNewLine | |
Write-Host $slash -Fore Yellow -Back Gray -NoNewLine | |
Write-Host "$($script:K.Current.Name)" -Fore Black -Back Yellow -NoNewLine | |
Write-Host $arrow -Fore Yellow -NoNewLine | |
return " " | |
} | |
# Aliases | |
Set-Alias -Name k -Value Invoke-KubeCtl > $null | |
Set-Alias -Name kx -Value Select-KubeContext > $null | |
Set-Alias -Name ns -Value Select-KubeNamespace > $null | |
Set-Alias -Name rs -Value Select-KubeResource > $null | |
# Context commands | |
Set-Alias -Name yaml -Value Get-KubeYaml > $null | |
Set-Alias -Name jp -Value Get-KubeJsonPath > $null | |
Set-Alias -Name desc -Value Get-KubeDescribeResource > $null | |
Set-Alias -Name delete -Value Delete-KubeResource > $null | |
Set-Alias -Name restart -Value Restart-KubeResource > $null | |
Set-Alias -Name w8 -Value WaitFor-KubeResource > $null | |
Set-Alias -Name pf -Value Invoke-KubePortForward > $null | |
Set-Alias -Name logs -Value Get-KubeLogs > $null | |
Set-Alias -Name flogs -Value Follow-KubeLogs > $null | |
Set-Alias -Name x -Value Invoke-KubePodCmd > $null | |
reload -Hard | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment