Skip to content

Instantly share code, notes, and snippets.

@ctsstc
Forked from levibrown/kube_commands.rb
Last active October 17, 2019 22:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctsstc/637cddd7f6df608c8861ba0cdd837642 to your computer and use it in GitHub Desktop.
Save ctsstc/637cddd7f6df608c8861ba0cdd837642 to your computer and use it in GitHub Desktop.
A CLI for Common G5 Kube Commands
#!/usr/bin/env ruby
# Setup:
# 1) `gem install highline`
# 2) save this file to a local folder
# 3) rename the file to remove extension `mv kube_commands.rb kube_command`
# 4) change permissions `chmod 755 kube_commands`
# 5) link to your /usr/local/bin `ln -s $PWD/kube_command /usr/local/bin/`
# 6) in a new shell you should now be able to run `kube_commands`
# 7) add new commands and add to this gist
require 'highline'
# require 'pry'
require 'optparse'
Options = Struct.new(:env, :app, :container)
class Parser
def self.parse
args = Options.new
opt_parser = OptionParser.new do |opts|
opts.banner = 'Usage: kube_controls [options]'
opts.on('-eENV', '--env=ENV', "Target environment i.e. ['rd-earth', 'rd-fire', 'rd-wind', 'default']") do |e|
args.env = e
end
opts.on('-aAPP', '--app=APP', 'Target Application') do |a|
args.app = a
end
opts.on('-cCONTAINER', '--container=CONTAINER', "Target Container i.e. ['rails-server', 'nginx-proxy']") do |c|
args.container = c
end
opts.on('-h', '--help', 'Prints this help') do
puts opts
exit
end
end
opt_parser.parse!
args
end
end
# Glorified CLI Decorator
class Chooser
attr_reader :cli
def initialize(cli)
@cli = cli
end
def choose(what, items)
puts "\n"
if items.length == 1
puts "Selected only #{what}: #{items.first}"
items.first
elsif items.length > 1
cli.choose do |menu|
menu.prompt = "Select #{what}: "
items.each do |item|
menu.choice(item)
end
end
else
raise "Error: No items for: #{what}?"
end
end
end
options = Parser.parse
cli = HighLine.new
chooser = Chooser.new(cli)
HighLine::Menu.index_color = :rgb_77bbff
if options.env
env = options.env
else
envs = `kubectl get ns -o=custom-columns=NAME:.metadata.name`
envs = envs.split(/\n/).drop(1)
env = chooser.choose('Deploy Environment', envs)
end
if options.app
selected_app = options.app
else
deps = `kubectl get deployments --output=name --namespace #{env}`
apps = deps.split(/\n/).map do |app|
app[%r{/([a-zA-Z]*)-}, 1]
end
selected_app = chooser.choose('App', apps.uniq)
end
pods = `kubectl get pods -o=custom-columns=NAME:.metadata.name --namespace #{env}`
app_pods = pods.split(/\n/).select do |pod|
pod.include?(selected_app)
end
selected_pod = chooser.choose('Pod', app_pods)
def append_container(ctx, chooser, options)
selected_container = if options.container
options.container
else
containers = `kubectl get pods #{ctx} -o jsonpath='{.spec.containers[*].name}'`
containers = containers.split(/\s/)
chooser.choose('Container', containers)
end
ctx += " -c #{selected_container}" if selected_container
ctx
end
ctx = "#{selected_pod} --namespace #{env}"
puts "\n"
done = false
until done
cli.choose do |menu|
menu.prompt = 'Select Task: '
menu.choice(:logs) do
ctx = append_container(ctx, chooser, options)
exec("kubectl logs -f #{ctx}")
end
menu.choice(:"shell (use printenv to check ENV vars)") do
ctx = append_container(ctx, chooser, options)
exec("kubectl exec -it #{ctx} -- /bin/bash")
end
menu.choice(:attach) do
ctx = append_container(ctx, chooser, options)
exec("kubectl attach #{ctx}")
end
menu.choice(:rake) do
task = cli.ask('Enter rake task: ')
`kubectl exec -it #{ctx} -- /bin/bash -c 'bin/#{task}'`
end
menu.choice(:describe) { puts `kubectl describe pod #{ctx}` }
menu.choice(:apply) { `kubectl apply -f k8s/#{env}.yaml --namespace=#{env}` }
menu.choice(:'restart (with patch)') do
deps = `kubectl get deployments --output=name --namespace #{env}`
deployments = deps.split(/\n/).select do |dep|
dep.include?(selected_app)
end
patches = cli.choose do |menu|
menu.prompt = "Select deployments to restart:\nAvailable Deployments: #{deployments} "
menu.choice(:all) { deployments }
menu.choice(:'change deployments') do
cli.say('Provide a comma separated list of available deployment paths: ')
cli.ask('Deployments: (deployment/example1, deployment/example2) | ', ->(str) { str.split(/,\s*/) })
end
menu.default = :all
end
patches.each do |patch|
`kubectl patch #{patch} -p '{"spec":{"template":{"metadata":{"annotations":{"forced-reload":"'$(date +%s)'"}}}}}' --namespace #{env}`
end
end
menu.choice(:exit) do
if !options.env || !options.app
cli.say("kube_commands --env=#{env} --app=#{selected_app}")
end
done = true
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment