26 Commits
v0.1 ... v0.4.0

Author SHA1 Message Date
Ahmet Alp Balkan
e82879a185 Update README.md 2017-11-09 14:15:52 -08:00
Ahmet Alp Balkan
8c17834c36 Merge pull request #15 from bnookala/use-rename-context
Use rename-context in place of set-context
2017-11-09 14:15:23 -08:00
Bhargav Nookala
9ed6690978 🔧 use rename-context in place of set-context 2017-11-03 12:49:03 -07:00
Ahmet Alp Balkan
ed2afa7572 Add GIFs to README.md
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-10-24 12:32:22 -07:00
Ahmet Alp Balkan
5d79a0663d Remove message for '-' in kubectx.zsh
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-10-23 23:56:21 -07:00
Ahmet Alp Balkan
e7131add7a Add Stargazers chart
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-10-22 19:22:23 -07:00
Ahmet Alp Balkan
fd91e53d1f 🎉 kubectx is now in homebrew-core 🎊
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-06-29 14:12:46 -07:00
Ahmet Alp Balkan
b06fcaf054 Update Homebrew Formula with v0.3.1
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-05-17 10:09:10 -07:00
Ahmet Alp Balkan
9a7358ce67 Merge pull request #9 from ahmetb/readlink
Fallback to readlink -f on macOS
2017-05-17 10:07:04 -07:00
Ahmet Alp Balkan
8e413fc8ac Fallback to readlink -f on macOS
BSD coreutils readlink doesn't have -f option, so
adding a Python one-liner feedback to eval symlinks/homedir.
Fixes #8.

Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-05-17 09:37:57 -07:00
Ahmet Alp Balkan
7e10232fdd Update Homebrew Formula with v0.3.0
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-05-16 22:19:32 -07:00
Ahmet Alp Balkan
572b3e83d9 Refactor completion descriptions on README
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-05-16 22:12:57 -07:00
Ahmet Alp Balkan
03f24f2625 Merge pull request #7 from ahmetb/short-names
Add --with-short-names option
2017-05-16 22:06:15 -07:00
Ahmet Alp Balkan
8dec9cf004 Document --with-short-names
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-05-16 22:05:52 -07:00
Ahmet Alp Balkan
a376b02e88 Add --with-short-names option
This allows linking as "kctx" and "kns" to prevent overlap with kubectl Tab
completion when user hits `ku<Tab>`. Fixes #3.

Also fixed variables KUBECTX and PREV leaking to zsh shell once the _kubectx
function is invoked.

Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-05-16 22:01:46 -07:00
Ahmet Alp Balkan
da3f814280 Merge pull request #6 from ahmetb/wip-kubens
Add kubens tool for namespace switching
2017-05-16 20:31:15 -07:00
Ahmet Alp Balkan
d441505348 Add kubens tool for namespace switching
Fixes #1. Now kubectx also ships with kubens.

Extracted utility functions to a utils.bash file, loaded
from ../include/utils.bash.

Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-05-16 19:06:58 -07:00
Ahmet Alp Balkan
c49f975e45 Merge pull request #4 from swestcott/master
Fix context discovery
2017-05-15 19:34:28 -07:00
Simon Westcott
8c6cf84801 Unified context discovery 2017-05-12 09:05:02 +01:00
Simon Westcott
d04543ffef Fix context discovery 2017-05-11 12:44:11 +01:00
Ahmet Alp Balkan
d1c04555f4 Update readmes
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-04-26 09:49:46 -07:00
Ahmet Alp Balkan
6e2f181518 Update brew formula for v0.2.0
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-04-26 09:42:08 -07:00
Ahmet Alp Balkan
5933a7bbf8 Add zsh completion script (finally)
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-04-26 09:39:24 -07:00
Ahmet Alp Balkan
a19b9535f6 Formula fixes
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-04-25 13:28:10 -07:00
Ahmet Alp Balkan
a861562803 Formula polishing
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-04-25 13:21:42 -07:00
Ahmet Alp Balkan
c4b6ad9517 Add a homebrew formula
Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
2017-04-25 12:58:58 -07:00
12 changed files with 298 additions and 76 deletions

26
Formula/kubectx.rb Normal file
View File

@@ -0,0 +1,26 @@
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.3.1.tar.gz"
sha256 "4e995f5bec6f41c8d5b6e77f413a58ead077816348e72de26dde3655ec2b7d0b"
head "https://github.com/ahmetb/kubectx.git", :branch => "short-names"
bottle :unneeded
option "with-short-names", "link as \"kctx\" and \"kns\" instead"
def install
bin.install "kubectx" => build.with?("short-names") ? "kctx" : "kubectx"
bin.install "kubens" => build.with?("short-names") ? "kns" : "kubens"
include.install "utils.bash"
bash_completion.install "completion/kubectx.bash" => "kubectx"
bash_completion.install "completion/kubens.bash" => "kubens"
zsh_completion.install "completion/kubectx.zsh" => "_kubectx"
zsh_completion.install "completion/kubens.zsh" => "_kubens"
end
test do
system "which", build.with?("short-names") ? "kctx" : "kubectx"
system "which", build.with?("short-names") ? "kns" : "kubens"
end
end

View File

@@ -1,3 +1,12 @@
This repository provides both `kubectx` and `kubens` tools.
**`kubectx`** help you switch between clusters back and forth:
![kubectx demo GIF](img/kubectx-demo.gif)
**`kubens`** help you switch between Kubernetes namespaces smoothly:
![kubens demo GIF](img/kubens-demo.gif)
# 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,72 @@ Context "dublin" set.
Aliased "gke_ahmetb_europe-west1-b_dublin" as "dublin".
```
[Set up `bash` and `zsh` completion &rarr;](completion/README.md)
`kubectx` supports <kbd>Tab</kbd> completion on bash/zsh 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 shells.
-----
## Installation
**For macOS:**
:tada: kubectx is now in Homebrew! :confetti_ball:
> Use the [Homebrew](https://brew.sh/) package manager:
>
> brew install kubectx
>
> this will also set up bash/zsh 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.
> Note: If you installed kubectx before it was accepted to Homebrew core
> repository, reinstall with:
> `brew untap ahmetb/kubectx && brew uninstall --force kubectx && brew update && brew install kubectx`
**Other platforms:**
- Download the `kubectx` script
- Add it somewhere in your PATH
- Make it executable (`chmod +x`)
- You can also install bash/zsh [completion scripts](completion/) manually.
-----
Disclaimer: This is not an official Google product.
#### Stargazers over time
[![Stargazers over time](https://starcharts.herokuapp.com/ahmetb/kubectx.svg)](https://starcharts.herokuapp.com/ahmetb/kubectx)

View File

@@ -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
```

View File

@@ -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

12
completion/kubectx.zsh Normal file
View File

@@ -0,0 +1,12 @@
#compdef kubectx kctx=kubectx
local KUBECTX="${HOME}/.kube/kubectx"
PREV=""
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')))"
else
_arguments "1: :($(kubectl config get-contexts --output='name'))"
fi

8
completion/kubens.bash Normal file
View 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

2
completion/kubens.zsh Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

BIN
img/kubens-demo.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

36
kubectx
View File

@@ -21,29 +21,29 @@
set -eou pipefail
IFS=$'\n\t'
SCRIPT_DIR="$(dirname "$( readlink -f "${0}" 2>/dev/null || \
python -c "import os,sys; print(os.path.realpath(sys.argv[1]))" "${0}" )")"
if [[ -f "${SCRIPT_DIR}/utils.bash" ]]; then
source "${SCRIPT_DIR}/utils.bash"
else
source "${SCRIPT_DIR}/../include/utils.bash"
fi
KUBECTX="${HOME}/.kube/kubectx"
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
}
current_context() {
kubectl config view -o=jsonpath='{.current-context}'
}
get_contexts() {
kubectl config view \
-o=jsonpath='{range .contexts[*].name}{@}{"\n"}{end}'
}
list_contexts() {
set -u pipefail
local cur="$(current_context)"
@@ -89,7 +89,6 @@ set_context() {
}
swap_context() {
set -e
local ctx="$(read_context)"
if [[ -z "${ctx}" ]]; then
echo "error: No previous context found." >&2
@@ -108,7 +107,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 +119,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 +134,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

146
kubens Executable file
View File

@@ -0,0 +1,146 @@
#!/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'
SCRIPT_DIR="$(dirname "$( readlink -f "${0}" 2>/dev/null || \
python -c "import os,sys; print(os.path.realpath(sys.argv[1]))" "${0}" )")"
if [[ -f "${SCRIPT_DIR}/utils.bash" ]]; then
source "${SCRIPT_DIR}/utils.bash"
else
source "${SCRIPT_DIR}/../include/utils.bash"
fi
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
}
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 "$@"

11
utils.bash Normal file
View File

@@ -0,0 +1,11 @@
current_context() {
kubectl config view -o=jsonpath='{.current-context}'
}
get_contexts() {
kubectl config get-contexts -o=name | sort -n
}
get_namespaces() {
kubectl get namespaces -o=jsonpath='{range .items[*].metadata.name}{@}{"\n"}{end}'
}