-
-
Save ctsstc/637cddd7f6df608c8861ba0cdd837642 to your computer and use it in GitHub Desktop.
A CLI for Common G5 Kube Commands
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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