mirror of
https://github.com/ahmetb/kubectx.git
synced 2026-02-25 09:32:25 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d3295e5b7a | ||
|
|
3369d42e2d | ||
|
|
f48c4198e7 | ||
|
|
26d3422917 | ||
|
|
56e30d2b43 | ||
|
|
dcb43fdf1b | ||
|
|
e2f7dc0de2 | ||
|
|
9645e5c62c | ||
|
|
00a1e12bfb | ||
|
|
c3dd1e5deb | ||
|
|
a21638226f | ||
|
|
28e7c12f51 | ||
|
|
1652420a15 | ||
|
|
543e035090 | ||
|
|
a5e810b837 | ||
|
|
62f3f27889 | ||
|
|
4258f03446 | ||
|
|
b9614bd2e0 | ||
|
|
b3732b309e | ||
|
|
a1bce92cc8 | ||
|
|
1356c37cc0 |
29
.github/workflows/release.yml
vendored
Normal file
29
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: release
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ github.ref }}
|
||||
- name: Update new version for plugin 'ctx' in krew-index
|
||||
uses: rajatjindal/krew-release-bot@v0.0.31
|
||||
with:
|
||||
krew_template_file: .krew/ctx.yaml
|
||||
- name: Update new version for plugin 'ns' in krew-index
|
||||
uses: rajatjindal/krew-release-bot@v0.0.31
|
||||
with:
|
||||
krew_template_file: .krew/ns.yaml
|
||||
|
||||
|
||||
31
.krew/ctx.yaml
Normal file
31
.krew/ctx.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
apiVersion: krew.googlecontainertools.github.com/v1alpha2
|
||||
kind: Plugin
|
||||
metadata:
|
||||
name: ctx
|
||||
spec:
|
||||
homepage: https://github.com/ahmetb/kubectx
|
||||
shortDescription: Switch between contexts in your kubeconfig
|
||||
version: {{ .TagName }}
|
||||
description: |
|
||||
Also known as "kubectx", a utility to switch between context entries in
|
||||
your kubeconfig file efficiently.
|
||||
caveats: |
|
||||
If fzf is installed on your machine, you can interactively choose
|
||||
between the entries using the arrow keys, or by fuzzy searching
|
||||
as you type.
|
||||
See https://github.com/ahmetb/kubectx for customization and details.
|
||||
platforms:
|
||||
- selector:
|
||||
matchExpressions:
|
||||
- key: os
|
||||
operator: In
|
||||
values:
|
||||
- darwin
|
||||
- linux
|
||||
{{addURIAndSha "https://github.com/ahmetb/kubectx/archive/{{ .TagName }}.tar.gz" .TagName }}
|
||||
bin: kubectx
|
||||
files:
|
||||
- from: kubectx-*/kubectx
|
||||
to: .
|
||||
- from: kubectx-*/LICENSE
|
||||
to: .
|
||||
31
.krew/ns.yaml
Normal file
31
.krew/ns.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
apiVersion: krew.googlecontainertools.github.com/v1alpha2
|
||||
kind: Plugin
|
||||
metadata:
|
||||
name: ns
|
||||
spec:
|
||||
homepage: https://github.com/ahmetb/kubectx
|
||||
shortDescription: Switch between Kubernetes namespaces
|
||||
version: {{ .TagName }}
|
||||
description: |
|
||||
Also known as "kubens", a utility to set your current namespace and switch
|
||||
between them.
|
||||
caveats: |
|
||||
If fzf is installed on your machine, you can interactively choose
|
||||
between the entries using the arrow keys, or by fuzzy searching
|
||||
as you type.
|
||||
See https://github.com/ahmetb/kubectx for customization and details.
|
||||
platforms:
|
||||
- selector:
|
||||
matchExpressions:
|
||||
- key: os
|
||||
operator: In
|
||||
values:
|
||||
- darwin
|
||||
- linux
|
||||
{{addURIAndSha "https://github.com/ahmetb/kubectx/archive/{{ .TagName }}.tar.gz" .TagName }}
|
||||
bin: kubens
|
||||
files:
|
||||
- from: kubectx-*/kubens
|
||||
to: .
|
||||
- from: kubectx-*/LICENSE
|
||||
to: .
|
||||
@@ -3,7 +3,10 @@ before_install:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install -qq bats
|
||||
- sudo curl -fsSL -o /usr/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/v1.13.1/bin/linux/amd64/kubectl
|
||||
- sudo chmod +x /usr/bin/kubectl
|
||||
- sudo chmod +x /usr/bin/kubectl
|
||||
script:
|
||||
- basename /usr/bin
|
||||
- bats test/kubectx.bats
|
||||
- bats test/kubens.bats
|
||||
- shellcheck kubectx
|
||||
- shellcheck kubens
|
||||
|
||||
70
README.md
70
README.md
@@ -1,4 +1,13 @@
|
||||
# `kubectx` + `kubens`: Power tools for kubectl
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
This repository provides both `kubectx` and `kubens` tools.
|
||||
[Install →](#installation)
|
||||
|
||||
|
||||
**`kubectx`** helps you switch between clusters back and forth:
|
||||
@@ -9,18 +18,20 @@ This repository provides both `kubectx` and `kubens` tools.
|
||||
|
||||
# kubectx(1)
|
||||
|
||||
kubectx is an utility to manage and switch between kubectl(1) contexts.
|
||||
kubectx is a utility to manage and switch between kubectl(1) contexts.
|
||||
|
||||
```
|
||||
USAGE:
|
||||
kubectx : list the contexts
|
||||
kubectx <NAME> : switch to context <NAME>
|
||||
kubectx - : switch to the previous context
|
||||
kubectx -c, --current : show the current context name
|
||||
kubectx <NEW_NAME>=<NAME> : rename context <NAME> to <NEW_NAME>
|
||||
kubectx <NEW_NAME>=. : rename current-context to <NEW_NAME>
|
||||
kubectx -d <NAME> : delete context <NAME> ('.' for current-context)
|
||||
(this command won't delete the user/cluster entry
|
||||
that is used by the context)
|
||||
kubectx -u, --unset : unset the current context
|
||||
```
|
||||
|
||||
### Usage
|
||||
@@ -47,13 +58,14 @@ long context names. You don't have to remember full context names anymore.
|
||||
|
||||
# kubens(1)
|
||||
|
||||
kubens is an utility to switch between Kubernetes namespaces.
|
||||
kubens is a utility to switch between Kubernetes namespaces.
|
||||
|
||||
```
|
||||
USAGE:
|
||||
kubens : list the namespaces
|
||||
kubens <NAME> : change the active namespace
|
||||
kubens - : switch to the previous namespace
|
||||
kubens -c, --current : show the current namespace
|
||||
```
|
||||
|
||||
|
||||
@@ -75,9 +87,36 @@ Active namespace is "default".
|
||||
|
||||
## Installation
|
||||
|
||||
There are several installation options:
|
||||
|
||||
- As kubectl plugins (macOS/Linux)
|
||||
- macOS
|
||||
- Homebrew (recommended)
|
||||
- MacPorts
|
||||
- Linux
|
||||
- manual installation/upgrades
|
||||
- Arch Linux
|
||||
- Debian/Ubuntu
|
||||
|
||||
### Kubectl Plugins (macOS and Linux)
|
||||
|
||||
You can install and use [Krew](https://github.com/kubernetes-sigs/krew/) kubectl
|
||||
plugin manager to get `kubectx` and `kubens`. **NOTE:** This will not install
|
||||
shell completion scripts, if you want those, choose another installation method
|
||||
below.
|
||||
|
||||
```sh
|
||||
kubectl krew install ctx
|
||||
kubectl krew install ns
|
||||
```
|
||||
|
||||
After installing, the tools will be available as `kubectl ctx` and `kubectl ns`.
|
||||
|
||||
### macOS
|
||||
|
||||
:confetti_ball: Use the [Homebrew](https://brew.sh/) package manager:
|
||||
#### Homebrew
|
||||
|
||||
:confetti_ball: If you use [Homebrew](https://brew.sh/) you can install like this:
|
||||
|
||||
brew install kubectx
|
||||
|
||||
@@ -86,9 +125,15 @@ This command will set up bash/zsh/fish completion scripts automatically.
|
||||
- If you like to add context/namespace info to your shell prompt (`$PS1`),
|
||||
I recommend trying out [kube-ps1](https://github.com/jonmosco/kube-ps1).
|
||||
|
||||
#### MacPorts
|
||||
|
||||
If you use [MacPorts](https://www.macports.org) you can install like this:
|
||||
|
||||
sudo port install kubectx
|
||||
|
||||
### Linux
|
||||
|
||||
Since `kubectx`/`kubens` are written in Bash, you should be able to instal
|
||||
Since `kubectx`/`kubens` are written in Bash, you should be able to install
|
||||
them to any POSIX environment that has Bash installed.
|
||||
|
||||
- Download the `kubectx`, and `kubens` scripts.
|
||||
@@ -107,8 +152,8 @@ them to any POSIX environment that has Bash installed.
|
||||
ln -s /opt/kubectx/completion/kubectx.zsh ~/.oh-my-zsh/completions/_kubectx.zsh
|
||||
ln -s /opt/kubectx/completion/kubens.zsh ~/.oh-my-zsh/completions/_kubens.zsh
|
||||
```
|
||||
Note that the leading underscore seems to be a convention.
|
||||
If not using oh-my-zsh, you could link to `/usr/share/zsh/functions/Completion` (might require sudo), depending on the `$fpath` of your zsh installation.
|
||||
Note that the leading underscore seems to be a convention. If completion doesn't work, add `autoload -U compinit && compinit` to your `.zshrc` (similar to [`zsh-completions`](https://github.com/zsh-users/zsh-completions/blob/master/README.md#oh-my-zsh)).
|
||||
If not using oh-my-zsh, you could link to `/usr/share/zsh/functions/Completion` (might require sudo), depending on the `$fpath` of your zsh installation.
|
||||
In case of error, calling `compaudit` might help.
|
||||
- For bash:
|
||||
```bash
|
||||
@@ -140,9 +185,11 @@ sudo ln -s /opt/kubectx/kubens /usr/local/bin/kubens
|
||||
|
||||
#### Arch Linux
|
||||
|
||||
An unofficial [AUR package](https://aur.archlinux.org/packages/kubectx) `kubectx`
|
||||
is available. Install instructions can be found on the [Arch
|
||||
wiki](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages).
|
||||
Available as official Arch Linux package. Install it via:
|
||||
|
||||
```bash
|
||||
sudo pacman -S kubectx
|
||||
```
|
||||
|
||||
#### Debian/Ubuntu
|
||||
|
||||
@@ -173,7 +220,7 @@ If you like to customize the colors indicating the current namespace or context,
|
||||
|
||||
```
|
||||
export KUBECTX_CURRENT_FGCOLOR=$(tput setaf 6) # blue text
|
||||
export KUBECTX_CURRENT_BGCOLOR=$(tput setaf 7) # white background
|
||||
export KUBECTX_CURRENT_BGCOLOR=$(tput setab 7) # white background
|
||||
```
|
||||
|
||||
Colors in the output can be disabled by setting the
|
||||
@@ -191,7 +238,8 @@ Colors in the output can be disabled by setting the
|
||||
| _“Also using it on a daily basis. This and my zsh config that shows me the current k8s context 😉”_ – [@puja108](https://twitter.com/puja108/status/928742521139810305) |
|
||||
| _“Lately I've found myself using the kubens command more than kubectx. Both very useful though :-)”_ – [@stuartleeks](https://twitter.com/stuartleeks/status/928562850464907264) |
|
||||
| _“yeah kubens rocks!”_ – [@embano1](https://twitter.com/embano1/status/928698440732815360) |
|
||||
| _“Special thanks to Ahmet Alp Balkan for creating kubectx, kubens, and kubectl aliases, as these tools made my life better.”_ – [@strebeld](https://medium.com/@strebeld/5-ways-to-enhance-kubectl-ux-97c8893227a)
|
||||
| _“Special thanks to Ahmet Alp Balkan for creating kubectx, kubens, and kubectl aliases, as these tools made my life better.”_ – [@strebeld](https://medium.com/@strebeld/5-ways-to-enhance-kubectl-ux-97c8893227a) |
|
||||
| _“❤️ this shell script @ahmetb wrote to help make switching between kubectl config contexts a breeze.”_ – [@briandanowski](https://twitter.com/briandanowski/status/1085409568165896193) |
|
||||
|
||||
> If you liked `kubectx`, you may like my [`kubectl-aliases`](https://github.com/ahmetb/kubectl-aliases) project, too.
|
||||
|
||||
|
||||
@@ -2,11 +2,17 @@
|
||||
|
||||
local KUBECTX="${HOME}/.kube/kubectx"
|
||||
PREV=""
|
||||
|
||||
local all_contexts="$(kubectl config get-contexts --output='name')"
|
||||
if [ -f "$KUBECTX" ]; then
|
||||
# show '-' only if there's a saved previous context
|
||||
local PREV=$(cat "${KUBECTX}")
|
||||
_arguments "1: :(-
|
||||
$(kubectl config get-contexts --output='name'))"
|
||||
|
||||
_arguments \
|
||||
"-d:*: :(${all_contexts})" \
|
||||
"(- *): :(- ${all_contexts})"
|
||||
else
|
||||
_arguments "1: :($(kubectl config get-contexts --output='name'))"
|
||||
_arguments \
|
||||
"-d:*: :(${all_contexts})" \
|
||||
"(- *): :(${all_contexts})"
|
||||
fi
|
||||
|
||||
44
kubectx
44
kubectx
@@ -22,21 +22,30 @@ set -eou pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
SELF_CMD="$0"
|
||||
|
||||
KUBECTX="${XDG_CACHE_HOME:-$HOME/.kube}/kubectx"
|
||||
|
||||
usage() {
|
||||
cat <<"EOF"
|
||||
local SELF
|
||||
SELF="kubectx"
|
||||
if [[ "$(basename "$0")" == kubectl-* ]]; then # invoked as plugin
|
||||
SELF="kubectl ctx"
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
USAGE:
|
||||
kubectx : list the contexts
|
||||
kubectx <NAME> : switch to context <NAME>
|
||||
kubectx - : switch to the previous context
|
||||
kubectx <NEW_NAME>=<NAME> : rename context <NAME> to <NEW_NAME>
|
||||
kubectx <NEW_NAME>=. : rename current-context to <NEW_NAME>
|
||||
kubectx -d <NAME> [<NAME...>] : delete context <NAME> ('.' for current-context)
|
||||
$SELF : list the contexts
|
||||
$SELF <NAME> : switch to context <NAME>
|
||||
$SELF - : switch to the previous context
|
||||
$SELF -c, --current : show the current context name
|
||||
$SELF <NEW_NAME>=<NAME> : rename context <NAME> to <NEW_NAME>
|
||||
$SELF <NEW_NAME>=. : rename current-context to <NEW_NAME>
|
||||
$SELF -d <NAME> [<NAME...>] : delete context <NAME> ('.' for current-context)
|
||||
(this command won't delete the user/cluster entry
|
||||
that is used by the context)
|
||||
$SELF -u, --unset : unset the current context
|
||||
|
||||
kubectx -h,--help : show this message
|
||||
$SELF -h,--help : show this message
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -106,7 +115,7 @@ choose_context_interactive() {
|
||||
local choice
|
||||
choice="$(_KUBECTX_FORCE_COLOR=1 \
|
||||
FZF_DEFAULT_COMMAND="${SELF_CMD}" \
|
||||
fzf --ansi || true)"
|
||||
fzf --ansi --no-preview || true)"
|
||||
if [[ -z "${choice}" ]]; then
|
||||
echo 2>&1 "error: you did not choose any of the options"
|
||||
exit 1
|
||||
@@ -148,6 +157,11 @@ rename_context() {
|
||||
old_name="$(current_context)"
|
||||
fi
|
||||
|
||||
if ! context_exists "${old_name}"; then
|
||||
echo "error: Context \"${old_name}\" not found, can't rename it." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if context_exists "${new_name}"; then
|
||||
echo "Context \"${new_name}\" exists, deleting..." >&2
|
||||
$KUBECTL config delete-context "${new_name}" 1>/dev/null 2>&1
|
||||
@@ -172,6 +186,11 @@ delete_context() {
|
||||
$KUBECTL config delete-context "${ctx}"
|
||||
}
|
||||
|
||||
unset_context() {
|
||||
echo "Unsetting current context." >&2
|
||||
$KUBECTL config unset current-context
|
||||
}
|
||||
|
||||
main() {
|
||||
if hash kubectl 2>/dev/null; then
|
||||
KUBECTL=kubectl
|
||||
@@ -202,6 +221,13 @@ main() {
|
||||
elif [[ "$#" -eq 1 ]]; then
|
||||
if [[ "${1}" == "-" ]]; then
|
||||
swap_context
|
||||
elif [[ "${1}" == '-c' || "${1}" == '--current' ]]; then
|
||||
# we don't call current_context here for two reasons:
|
||||
# - it does not fail when current-context property is not set
|
||||
# - it does not return a trailing newline
|
||||
kubectl config current-context
|
||||
elif [[ "${1}" == '-u' || "${1}" == '--unset' ]]; then
|
||||
unset_context
|
||||
elif [[ "${1}" == '-h' || "${1}" == '--help' ]]; then
|
||||
usage
|
||||
elif [[ "${1}" =~ ^-(.*) ]]; then
|
||||
|
||||
26
kubens
26
kubens
@@ -22,15 +22,23 @@ set -eou pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
SELF_CMD="$0"
|
||||
|
||||
KUBENS_DIR="${XDG_CACHE_HOME:-$HOME/.kube}/kubens"
|
||||
|
||||
usage() {
|
||||
cat <<"EOF"
|
||||
local SELF
|
||||
SELF="kubens"
|
||||
if [[ "$(basename "$0")" == kubectl-* ]]; then # invoked as plugin
|
||||
SELF="kubectl ns"
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
USAGE:
|
||||
kubens : list the namespaces in the current context
|
||||
kubens <NAME> : change the active namespace of current context
|
||||
kubens - : switch to the previous namespace in this context
|
||||
kubens -h,--help : show this message
|
||||
$SELF : list the namespaces in the current context
|
||||
$SELF <NAME> : change the active namespace of current context
|
||||
$SELF - : switch to the previous namespace in this context
|
||||
$SELF -c, --current : show the current namespace
|
||||
$SELF -h,--help : show this message
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -66,7 +74,9 @@ escape_context_name() {
|
||||
}
|
||||
|
||||
namespace_file() {
|
||||
local ctx="$(escape_context_name "${1}")"
|
||||
local ctx
|
||||
|
||||
ctx="$(escape_context_name "${1}")"
|
||||
echo "${KUBENS_DIR}/${ctx}"
|
||||
}
|
||||
|
||||
@@ -106,7 +116,7 @@ choose_namespace_interactive() {
|
||||
local choice
|
||||
choice="$(_KUBECTX_FORCE_COLOR=1 \
|
||||
FZF_DEFAULT_COMMAND="${SELF_CMD}" \
|
||||
fzf --ansi || true)"
|
||||
fzf --ansi --no-preview || true)"
|
||||
if [[ -z "${choice}" ]]; then
|
||||
echo 2>&1 "error: you did not choose any of the options"
|
||||
exit 1
|
||||
@@ -195,6 +205,8 @@ main() {
|
||||
usage
|
||||
elif [[ "${1}" == "-" ]]; then
|
||||
swap_namespace
|
||||
elif [[ "${1}" == '-c' || "${1}" == '--current' ]]; then
|
||||
current_namespace
|
||||
elif [[ "${1}" =~ ^-(.*) ]]; then
|
||||
echo "error: unrecognized flag \"${1}\"" >&2
|
||||
usage
|
||||
|
||||
@@ -113,6 +113,33 @@ load common
|
||||
[ "$status" -eq 1 ]
|
||||
}
|
||||
|
||||
@test "-c/--current fails when no context set" {
|
||||
use_config config1
|
||||
|
||||
run "${COMMAND}" -c
|
||||
echo "$output"
|
||||
[ $status -eq 1 ]
|
||||
run "${COMMAND}" --current
|
||||
echo "$output"
|
||||
[ $status -eq 1 ]
|
||||
}
|
||||
|
||||
@test "-c/--current prints the current context" {
|
||||
use_config config1
|
||||
|
||||
run "${COMMAND}" user1@cluster1
|
||||
[ $status -eq 0 ]
|
||||
|
||||
run "${COMMAND}" -c
|
||||
echo "$output"
|
||||
[ $status -eq 0 ]
|
||||
[[ "$output" = "user1@cluster1" ]]
|
||||
run "${COMMAND}" --current
|
||||
echo "$output"
|
||||
[ $status -eq 0 ]
|
||||
[[ "$output" = "user1@cluster1" ]]
|
||||
}
|
||||
|
||||
@test "rename context" {
|
||||
use_config config2
|
||||
|
||||
@@ -212,3 +239,16 @@ load common
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" = "user2@cluster1" ]]
|
||||
}
|
||||
|
||||
@test "unset selected context" {
|
||||
use_config config2
|
||||
|
||||
run ${COMMAND} user1@cluster1
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run ${COMMAND} -u
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run ${COMMAND} -c
|
||||
[ "$status" -ne 0 ]
|
||||
}
|
||||
|
||||
@@ -102,3 +102,43 @@ load common
|
||||
[[ "$status" -eq 1 ]]
|
||||
[[ "$output" = *"current-context is not set"* ]]
|
||||
}
|
||||
|
||||
@test "-c/--current works when no namespace is set on context" {
|
||||
use_config config1
|
||||
switch_context user1@cluster1
|
||||
|
||||
run ${COMMAND} "-c"
|
||||
echo "$output"
|
||||
[[ "$status" -eq 0 ]]
|
||||
[[ "$output" = "default" ]]
|
||||
run ${COMMAND} "--current"
|
||||
echo "$output"
|
||||
[[ "$status" -eq 0 ]]
|
||||
[[ "$output" = "default" ]]
|
||||
}
|
||||
|
||||
@test "-c/--current prints the namespace after it is set" {
|
||||
use_config config1
|
||||
switch_context user1@cluster1
|
||||
${COMMAND} ns1
|
||||
|
||||
run ${COMMAND} "-c"
|
||||
echo "$output"
|
||||
[[ "$status" -eq 0 ]]
|
||||
[[ "$output" = "ns1" ]]
|
||||
run ${COMMAND} "--current"
|
||||
echo "$output"
|
||||
[[ "$status" -eq 0 ]]
|
||||
[[ "$output" = "ns1" ]]
|
||||
}
|
||||
|
||||
@test "-c/--current fails when current context is not set" {
|
||||
use_config config1
|
||||
run ${COMMAND} -c
|
||||
echo "$output"
|
||||
[[ "$status" -eq 1 ]]
|
||||
|
||||
run ${COMMAND} --current
|
||||
echo "$output"
|
||||
[[ "$status" -eq 1 ]]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user