Skip to content

Instantly share code, notes, and snippets.

@felixbuenemann
Created April 22, 2017 19:37
Show Gist options
  • Save felixbuenemann/ae71bc1111b495cbdba03070b71fa55e to your computer and use it in GitHub Desktop.
Save felixbuenemann/ae71bc1111b495cbdba03070b71fa55e to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'yaml'
prog = File.basename $0
usage = <<EOF
#{prog} - kubectl/kubetail Wrapper for Deis Workflow Apps.
Usage:
#{prog} [deis git remote] [kubectl options...] [--app deis app]
#{prog} [deis git remote] [search suffix] [kubetail options...] [--app deis app]
The deis git remote name default to "deis" if omitted.
The deis app name / k8s namespace defaults to the deis git repo name if omitted.
Examples:
kd get po # get all pods in app namespace for deis cluster
kd production get po # get all pods in namespace for production cluster
kd get po --app foo # override app name
kd get pod --kubeconfig ~/.kube/my-custom-config # custom kubeconfig path
kd tail # tail all pods in app namespace
kd tail web # tail all web proc type pods in app namespace
kd tail my-app-web-1234-jghfi # tail log for a specific pod
Note:
This tool must be called in a git checkout for a deis workflow app, because it
selects the right kubernetes context based on the deis builder git remote url.
#{prog} tail requires kubetail from: https://github.com/johanhaleby/kubetail
EOF
if ARGV.empty?
puts usage
exit
end
is_git = system 'git rev-parse --show-toplevel > /dev/null'
exit $?.exitstatus unless is_git
# Support --kubeconfig switch to override config location
kubeconfig_args = %w(config view)
kubeconfig_idx = ARGV.find_index {|arg| arg == '--kubeconfig' or arg.start_with? '--kubeconfig=' }
unless kubeconfig_idx.nil?
kubeconfig_args.unshift ARGV[kubeconfig_idx+1] if ARGV[kubeconfig_idx] == '--kubeconfig'
kubeconfig_args.unshift ARGV[kubeconfig_idx]
end
kube_config_yaml = IO.popen(['kubectl', *kubeconfig_args]).read
exit $?.exitstatus unless $?.success?
kube_config = YAML.load kube_config_yaml
# current_kube_context = kube_config['current-context']
git_remotes = `git remote -v`.split(/\n/)
deis_remotes = git_remotes.grep(/^([^\t]+)\tssh:\/\/git@deis-builder\.([^:]+):2222\/(.+)\.git \(push\)$/) do |_|
{'remote' => $1, 'domain' => $2, 'app' => $3}
end
remote_arg = ARGV.shift
active_remote_idx = deis_remotes.find_index {|r| r['remote'] == remote_arg }
if active_remote_idx.nil?
ARGV.unshift remote_arg
remote_arg = 'deis'
active_remote_idx = deis_remotes.find_index {|r| r['remote'] == remote_arg }
end
if active_remote_idx.nil?
$stderr.puts "No deis git remote #{remote_arg.inspect} found"
exit 2
end
active_remote = deis_remotes[active_remote_idx]
matching_context = kube_config['contexts'].find do |context|
kube_config['clusters'].find do |cluster|
cluster['name'] == context['context']['cluster'] and
cluster['cluster']['server'].end_with? active_remote['domain']
end
end
if matching_context.nil?
$stderr.puts "No kube context with a server ending in #{active_remote['domain'].inspect} found"
exit 3
end
context = matching_context['name']
namespace = active_remote['app']
# Allow overriding app with --app foo or --app=foo
app_idx = ARGV.find_index {|arg| arg == '--app' or arg.start_with? '--app=' }
unless app_idx.nil?
arg = ARGV.delete_at app_idx
if arg == '--app'
namespace = ARGV.delete_at app_idx # shifted left by prev delete
else
namespace = arg.split('=', 2)[1]
end
end
command_idx = ARGV.find_index {|arg| arg[0] != '-' }
command = ARGV.delete_at command_idx unless command_idx.nil?
global_args = %W[
--context #{context}
--namespace #{namespace}
]
if command == 'tail' # kd tail web
suffix_idx = ARGV.find_index {|arg| arg[0] != '-' }
suffix = suffix_idx && ARGV.delete_at(suffix_idx) || ''
prefix = "#{namespace}-"
search_term = suffix.start_with?(prefix) ? suffix : prefix + suffix
ARGV.unshift search_term, *global_args
exec 'kubetail', *ARGV
else # kd get po
ARGV.unshift command unless command.nil?
ARGV.unshift *global_args
exec 'kubectl', *ARGV
end
@felixbuenemann
Copy link
Author

felixbuenemann commented Apr 22, 2017

The script only works if the domain of your deis controller matches your k8s controller, eg. deis-builder.staging.example.com and k8s.staging.example.com. If your KUBECONFIG contains multiple contexts, the first context with a matching server name will be used.

Install to /usr/local/bin/kd with:

curl -sfLO https://gist.github.com/felixbuenemann/ae71bc1111b495cbdba03070b71fa55e/raw/kd && chmod +x kd && mv -i kd /usr/local/bin/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment