mirror of
https://github.com/ahmetb/kubectx.git
synced 2026-02-23 00:22:18 +00:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80336137bd | ||
|
|
1c9b5c54e8 | ||
|
|
b188f4da88 | ||
|
|
57893cb668 | ||
|
|
8da629d98e | ||
|
|
b2992aa0df | ||
|
|
2f33693466 | ||
|
|
c813642dc3 | ||
|
|
12575f8ce4 | ||
|
|
46d4236f1a | ||
|
|
7ae68ada83 | ||
|
|
146b67d2b0 | ||
|
|
e3ceb14db5 | ||
|
|
6e250aecb6 | ||
|
|
d613c37c16 | ||
|
|
61f1aa8fd7 | ||
|
|
8390860474 | ||
|
|
394288edc0 | ||
|
|
dc6d2e57b3 | ||
|
|
aa215b9eeb | ||
|
|
e82879a185 | ||
|
|
8c17834c36 | ||
|
|
9ed6690978 | ||
|
|
ed2afa7572 | ||
|
|
5d79a0663d | ||
|
|
e7131add7a | ||
|
|
fd91e53d1f | ||
|
|
b06fcaf054 | ||
|
|
9a7358ce67 | ||
|
|
8e413fc8ac | ||
|
|
7e10232fdd | ||
|
|
572b3e83d9 | ||
|
|
03f24f2625 | ||
|
|
8dec9cf004 | ||
|
|
a376b02e88 | ||
|
|
da3f814280 | ||
|
|
d441505348 | ||
|
|
c49f975e45 | ||
|
|
8c6cf84801 | ||
|
|
d04543ffef | ||
|
|
d1c04555f4 | ||
|
|
6e2f181518 |
@@ -1,18 +0,0 @@
|
||||
class Kubectx < Formula
|
||||
desc "Tool that can switch between kubectl contexts easily and create aliases"
|
||||
homepage "https://github.com/ahmetb/kubectx"
|
||||
url "https://github.com/ahmetb/kubectx/archive/v0.2.0.tar.gz"
|
||||
sha256 "9fb6557416e4be3ef7e9701527f89fa73a1a0545a3cafbe6bed7527061c6cfb7"
|
||||
|
||||
bottle :unneeded
|
||||
|
||||
def install
|
||||
bin.install "kubectx"
|
||||
bash_completion.install "completion/kubectx.bash" => "kubectx"
|
||||
zsh_completion.install "completion/kubectx.zsh" => "_kubectx"
|
||||
end
|
||||
|
||||
test do
|
||||
system "which", "kubectx"
|
||||
end
|
||||
end
|
||||
112
README.md
112
README.md
@@ -1,3 +1,12 @@
|
||||
This repository provides both `kubectx` and `kubens` tools.
|
||||
|
||||
|
||||
**`kubectx`** help you switch between clusters back and forth:
|
||||

|
||||
|
||||
**`kubens`** help you switch between Kubernetes namespaces smoothly:
|
||||

|
||||
|
||||
# kubectx(1)
|
||||
|
||||
kubectx is an utility to manage and switch between kubectl(1) contexts.
|
||||
@@ -5,16 +14,13 @@ kubectx is an utility to manage and switch between kubectl(1) contexts.
|
||||
```
|
||||
USAGE:
|
||||
kubectx : list the contexts
|
||||
kubectx <NAME> : switch to context
|
||||
kubectx <NAME> : switch to context <NAME>
|
||||
kubectx - : switch to the previous context
|
||||
kubectx <NEW_NAME>=<NAME> : create alias for context
|
||||
kubectx <NEW_NAME>=<NAME> : rename context <NAME> to <NEW_NAME>
|
||||
kubectx -h,--help : show this message
|
||||
```
|
||||
|
||||
Purpose of this project is to provide an utility and facilitate discussion
|
||||
about how `kubectl` can manage contexts better.
|
||||
|
||||
## Example
|
||||
### Usage
|
||||
|
||||
```sh
|
||||
$ kubectx minikube
|
||||
@@ -31,12 +37,100 @@ Context "dublin" set.
|
||||
Aliased "gke_ahmetb_europe-west1-b_dublin" as "dublin".
|
||||
```
|
||||
|
||||
[Set up `bash` and `zsh` completion →](completion/README.md)
|
||||
`kubectx` supports <kbd>Tab</kbd> completion on bash/zsh/fish shells to help with
|
||||
long context names. You don't have to remember full context names anymore.
|
||||
|
||||
### Help wanted
|
||||
-----
|
||||
|
||||
- [ ] homebrew formula/tap that installs the script and completions
|
||||
# kubens(1)
|
||||
|
||||
kubens is an utility to switch between Kubernetes namespaces.
|
||||
|
||||
```
|
||||
USAGE:
|
||||
kubens : list the namespaces
|
||||
kubens <NAME> : change the active namespace
|
||||
kubens - : switch to the previous namespace
|
||||
kubens -h,--help : show this message
|
||||
```
|
||||
|
||||
|
||||
### Usage
|
||||
|
||||
```sh
|
||||
$ kubens kube-system
|
||||
Context "test" set.
|
||||
Active namespace is "kube-system".
|
||||
|
||||
$ kubens -
|
||||
Context "test" set.
|
||||
Active namespace is "default".
|
||||
```
|
||||
|
||||
`kubens` also supports <kbd>Tab</kbd> completion on bash/zsh/fish shells.
|
||||
|
||||
-----
|
||||
|
||||
## Installation
|
||||
|
||||
**macOS:**
|
||||
|
||||
:confetti_ball: Use the [Homebrew](https://brew.sh/) package manager:
|
||||
|
||||
brew install kubectx
|
||||
|
||||
This command will set up bash/zsh/fish completion scripts automatically.
|
||||
|
||||
|
||||
- Running `brew install` with `--with-short-names` will install tools with names
|
||||
`kctx` and `kns` to prevent prefix collision with `kubectl` name.
|
||||
|
||||
- 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).
|
||||
|
||||
**Linux:**
|
||||
|
||||
Since `kubectx`/`kubens` are written in Bash, you should be able to instal
|
||||
them to any POSIX environment that has Bash installed.
|
||||
|
||||
- Download the `kubectx`, and `kubens` scripts.
|
||||
- Either:
|
||||
- save them all to somewhere in your `PATH`,
|
||||
- or save them to a directory, then create symlinks to `kubectx`/`kubens` from
|
||||
somewhere in your `PATH`, like `/usr/local/bin`
|
||||
- Make `kubectx` and `kubens` executable (`chmod +x ...`)
|
||||
- Figure out how to install bash/zsh/fish [completion scripts](completion/).
|
||||
|
||||
Example installation steps:
|
||||
|
||||
``` bash
|
||||
sudo git clone https://github.com/ahmetb/kubectx /opt/kubectx
|
||||
sudo ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx
|
||||
sudo ln -s /opt/kubectx/kubens /usr/local/bin/kubens
|
||||
```
|
||||
|
||||
-----
|
||||
|
||||
#### Users
|
||||
|
||||
| What are others saying about kubectx? |
|
||||
| ---- |
|
||||
| _“Thank you for kubectx & kubens - I use them all the time & have them in my k8s toolset to maintain happiness :) ”_ – [@pbouwer](https://twitter.com/pbouwer/status/925896377929949184) |
|
||||
| _“I can't imagine working without kubectx and especially kubens anymore. It's pure gold.”_ – [@timoreimann](https://twitter.com/timoreimann/status/925801946757419008) |
|
||||
| _“I'm liking kubectx from @ahmetb, makes it super-easy to switch #Kubernetes contexts [...]”_ — [@lizrice](https://twitter.com/lizrice/status/928556415517589505) |
|
||||
| _“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)
|
||||
|
||||
> If you liked `kubectx`, you may like my [`kubectl-aliases`](https://github.com/ahmetb/kubectl-aliases) project, too.
|
||||
|
||||
-----
|
||||
|
||||
Disclaimer: This is not an official Google product.
|
||||
|
||||
|
||||
#### Stargazers over time
|
||||
|
||||
[](https://starcharts.herokuapp.com/ahmetb/kubectx)
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
kubectx provides shell completion scripts to complete context names, making it
|
||||
even faster to switch between contexts easily.
|
||||
|
||||
## Bash setup
|
||||
|
||||
Copy the `kubectx.bash` file to your HOME directory:
|
||||
|
||||
```sh
|
||||
cp kubectx.bash ~/.kubectx.bash
|
||||
```
|
||||
|
||||
And source it in your `~/.bashrc` file by adding the line:
|
||||
|
||||
```sh
|
||||
[ -f ~/.kubectx.bash ] && source ~/.kubectx.bash
|
||||
```
|
||||
|
||||
Start a new shell, type `kubectx`, then hit <kbd>Tab</kbd> to see the existing
|
||||
contexts.
|
||||
|
||||
You can Add `TAB: menu-complete` to your `~/.inputrc` to cycle through the
|
||||
options with <kbd>Tab</kbd>.
|
||||
|
||||
## Zsh setup
|
||||
|
||||
`zsh` can leverage the `bash` completion scripts. Copy the `kubectx.bash` file
|
||||
to your HOME directory:
|
||||
|
||||
```sh
|
||||
cp kubectx.bash ~/.kubectx.bash
|
||||
```
|
||||
|
||||
And add the following to your `.zshrc`:
|
||||
|
||||
```sh
|
||||
[ -f ~/.kubectx.bash ] && source ~/.kubectx.bash
|
||||
```
|
||||
|
||||
Start a new shell, type `kubectx`, then hit <kbd>Tab</kbd> to see the existing
|
||||
contexts. If it does not work, modify the line above to:
|
||||
|
||||
```sh
|
||||
[ -f ~/.kubectx.bash ] && autoload bashcompinit && bashcompinit && \
|
||||
source ~/.kubectx.bash
|
||||
```
|
||||
@@ -2,7 +2,7 @@ _kube_contexts()
|
||||
{
|
||||
local curr_arg;
|
||||
curr_arg=${COMP_WORDS[COMP_CWORD]}
|
||||
COMPREPLY=( $(compgen -W "- $(kubectl config get-contexts | awk '{print $2}' | tail -n +2)" -- $curr_arg ) );
|
||||
COMPREPLY=( $(compgen -W "- $(kubectl config get-contexts --output='name')" -- $curr_arg ) );
|
||||
}
|
||||
|
||||
complete -F _kube_contexts kubectx
|
||||
complete -F _kube_contexts kubectx kctx
|
||||
|
||||
3
completion/kubectx.fish
Normal file
3
completion/kubectx.fish
Normal file
@@ -0,0 +1,3 @@
|
||||
# kubectx
|
||||
complete -f -c kubectx -a "- (kubectl config get-contexts --output='name')"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#compdef kubectx
|
||||
#compdef kubectx kctx=kubectx
|
||||
|
||||
KUBECTX="${HOME}/.kube/kubectx"
|
||||
local KUBECTX="${HOME}/.kube/kubectx"
|
||||
PREV=""
|
||||
if [ -f "$KUBECTX" ]; then
|
||||
# show '-' only if there's a saved previous context
|
||||
PREV=$(cat "${KUBECTX}")
|
||||
_arguments "1: :((-\:Back\ to\ ${PREV} \
|
||||
$(kubectl config get-contexts | awk '{print $2}' | tail -n +2)))"
|
||||
local PREV=$(cat "${KUBECTX}")
|
||||
_arguments "1: :((- \
|
||||
$(kubectl config get-contexts --output='name')))"
|
||||
else
|
||||
_arguments "1: :($(kubectl config get-contexts | awk '{print $2}' | tail -n +2))"
|
||||
_arguments "1: :($(kubectl config get-contexts --output='name'))"
|
||||
fi
|
||||
|
||||
8
completion/kubens.bash
Normal file
8
completion/kubens.bash
Normal file
@@ -0,0 +1,8 @@
|
||||
_kube_namespaces()
|
||||
{
|
||||
local curr_arg;
|
||||
curr_arg=${COMP_WORDS[COMP_CWORD]}
|
||||
COMPREPLY=( $(compgen -W "- $(kubectl get namespaces -o=jsonpath='{range .items[*].metadata.name}{@}{"\n"}{end}')" -- $curr_arg ) );
|
||||
}
|
||||
|
||||
complete -F _kube_namespaces kubens kns
|
||||
3
completion/kubens.fish
Normal file
3
completion/kubens.fish
Normal file
@@ -0,0 +1,3 @@
|
||||
# kubens
|
||||
complete -f -c kubens -a "(kubectl get ns -o=custom-columns=NAME:.metadata.name --no-headers)"
|
||||
|
||||
2
completion/kubens.zsh
Normal file
2
completion/kubens.zsh
Normal file
@@ -0,0 +1,2 @@
|
||||
#compdef kubens kns=kubens
|
||||
_arguments "1: :(- $(kubectl get namespaces -o=jsonpath='{range .items[*].metadata.name}{@}{"\n"}{end}'))"
|
||||
BIN
img/kubectx-demo.gif
Normal file
BIN
img/kubectx-demo.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 163 KiB |
BIN
img/kubens-demo.gif
Normal file
BIN
img/kubens-demo.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 226 KiB |
21
kubectx
21
kubectx
@@ -27,9 +27,9 @@ usage() {
|
||||
cat <<"EOF"
|
||||
USAGE:
|
||||
kubectx : list the contexts
|
||||
kubectx <NAME> : switch to context
|
||||
kubectx <NAME> : switch to context <NAME>
|
||||
kubectx - : switch to the previous context
|
||||
kubectx <NEW_NAME>=<NAME> : create alias for context
|
||||
kubectx <NEW_NAME>=<NAME> : rename context <NAME> to <NEW_NAME>
|
||||
kubectx -h,--help : show this message
|
||||
EOF
|
||||
exit 1
|
||||
@@ -40,8 +40,7 @@ current_context() {
|
||||
}
|
||||
|
||||
get_contexts() {
|
||||
kubectl config view \
|
||||
-o=jsonpath='{range .contexts[*].name}{@}{"\n"}{end}'
|
||||
kubectl config get-contexts -o=name | sort -n
|
||||
}
|
||||
|
||||
list_contexts() {
|
||||
@@ -89,7 +88,6 @@ set_context() {
|
||||
}
|
||||
|
||||
swap_context() {
|
||||
set -e
|
||||
local ctx="$(read_context)"
|
||||
if [[ -z "${ctx}" ]]; then
|
||||
echo "error: No previous context found." >&2
|
||||
@@ -108,7 +106,7 @@ cluster_of_context() {
|
||||
-o=jsonpath="{.contexts[?(@.name==\"${1}\")].context.cluster}"
|
||||
}
|
||||
|
||||
alias_context() {
|
||||
rename_context() {
|
||||
local old_name="${1}"
|
||||
local new_name="${2}"
|
||||
|
||||
@@ -120,11 +118,7 @@ alias_context() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
kubectl config set-context "${new_name}" \
|
||||
--cluster="${old_cluster}" \
|
||||
--user="${old_user}" \
|
||||
|
||||
echo "Aliased \"${old_name}\" as \"${new_name}\"." >&2
|
||||
kubectl config rename-context "${old_name}" "${new_name}"
|
||||
}
|
||||
|
||||
main() {
|
||||
@@ -139,9 +133,10 @@ main() {
|
||||
elif [[ "${1}" == '-h' || "${1}" == '--help' ]]; then
|
||||
usage
|
||||
elif [[ "${1}" =~ ^-(.*) ]]; then
|
||||
echo "error: unrecognized flag" >&2; usage
|
||||
echo "error: unrecognized flag \"${1}\"" >&2
|
||||
usage
|
||||
elif [[ "${1}" =~ (.+)=(.+) ]]; then
|
||||
alias_context "${BASH_REMATCH[2]}" "${BASH_REMATCH[1]}"
|
||||
rename_context "${BASH_REMATCH[2]}" "${BASH_REMATCH[1]}"
|
||||
else
|
||||
set_context "${1}"
|
||||
fi
|
||||
|
||||
145
kubens
Executable file
145
kubens
Executable file
@@ -0,0 +1,145 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# kubenx(1) is a utility to switch between Kubernetes namespaces.
|
||||
|
||||
# Copyright 2017 Google Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
[[ -n $DEBUG ]] && set -x
|
||||
|
||||
set -eou pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
KUBENS_DIR="${HOME}/.kube/kubens"
|
||||
|
||||
usage() {
|
||||
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
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
current_namespace() {
|
||||
local cur_ctx=$(current_context)
|
||||
ns="$(kubectl config view -o=jsonpath="{.contexts[?(@.name==\"${cur_ctx}\")].context.namespace}")"
|
||||
if [[ -z "${ns}" ]]; then
|
||||
echo "default"
|
||||
else
|
||||
echo "${ns}"
|
||||
fi
|
||||
}
|
||||
|
||||
current_context() {
|
||||
kubectl config view -o=jsonpath='{.current-context}'
|
||||
}
|
||||
|
||||
get_namespaces() {
|
||||
kubectl get namespaces -o=jsonpath='{range .items[*].metadata.name}{@}{"\n"}{end}'
|
||||
}
|
||||
|
||||
namespace_file() {
|
||||
local ctx="${1}"
|
||||
echo "${KUBENS_DIR}/${ctx}"
|
||||
}
|
||||
|
||||
read_namespace() {
|
||||
local f="$(namespace_file "${1}")"
|
||||
[[ -f "${f}" ]] && cat "${f}"
|
||||
}
|
||||
|
||||
save_namespace() {
|
||||
mkdir -p "${KUBENS_DIR}"
|
||||
local f="$(namespace_file "${1}")"
|
||||
local saved="$(read_namespace "${1}")"
|
||||
|
||||
if [[ "${saved}" != "${2}" ]]; then
|
||||
printf %s "${2}" > "${f}"
|
||||
fi
|
||||
}
|
||||
|
||||
switch_namespace() {
|
||||
local ctx="${1}"
|
||||
kubectl config set-context "${ctx}" --namespace="${2}"
|
||||
echo "Active namespace is \"${2}\".">&2
|
||||
}
|
||||
|
||||
set_namespace() {
|
||||
local ctx="$(current_context)"
|
||||
local prev="$(current_namespace)"
|
||||
|
||||
if grep -q ^"${1}"\$ <(get_namespaces); then
|
||||
switch_namespace "${ctx}" "${1}"
|
||||
|
||||
if [[ "${prev}" != "${1}" ]]; then
|
||||
save_namespace "${ctx}" "${prev}"
|
||||
fi
|
||||
else
|
||||
echo "error: no namespace exists with name \"${1}\".">&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
list_namespaces() {
|
||||
local cur="$(current_namespace)"
|
||||
|
||||
local yellow=$(tput setaf 3)
|
||||
local darkbg=$(tput setab 0)
|
||||
local normal=$(tput sgr0)
|
||||
|
||||
for c in $(get_namespaces); do
|
||||
if [[ "${c}" = "${cur}" ]]; then
|
||||
echo "${darkbg}${yellow}${c}${normal}"
|
||||
else
|
||||
echo "${c}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
swap_namespace() {
|
||||
local ctx="$(current_context)"
|
||||
local ns="$(read_namespace "${ctx}")"
|
||||
if [[ -z "${ns}" ]]; then
|
||||
echo "error: No previous namespace found for current context." >&2
|
||||
exit 1
|
||||
fi
|
||||
set_namespace "${ns}"
|
||||
}
|
||||
|
||||
main() {
|
||||
if [[ "$#" -eq 0 ]]; then
|
||||
list_namespaces
|
||||
elif [[ "$#" -eq 1 ]]; then
|
||||
if [[ "${1}" == '-h' || "${1}" == '--help' ]]; then
|
||||
usage
|
||||
elif [[ "${1}" == "-" ]]; then
|
||||
swap_namespace
|
||||
elif [[ "${1}" =~ ^-(.*) ]]; then
|
||||
echo "error: unrecognized flag \"${1}\"" >&2
|
||||
usage
|
||||
elif [[ "${1}" =~ (.+)=(.+) ]]; then
|
||||
alias_context "${BASH_REMATCH[2]}" "${BASH_REMATCH[1]}"
|
||||
else
|
||||
set_namespace "${1}"
|
||||
fi
|
||||
else
|
||||
echo "error: too many flags" >&2
|
||||
usage
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user