class Seira::NodePools
Constants
- SUMMARY
- VALID_ACTIONS
Attributes
action[R]
args[R]
context[R]
settings[R]
Public Class Methods
new(action:, args:, context:, settings:)
click to toggle source
# File lib/seira/node_pools.rb, line 15 def initialize(action:, args:, context:, settings:) @action = action @args = args @context = context @settings = settings end
Public Instance Methods
run()
click to toggle source
# File lib/seira/node_pools.rb, line 22 def run case action when 'help' run_help when 'list' run_list when 'list-nodes' run_list_nodes when 'add' run_add when 'cordon' run_cordon when 'drain' run_drain when 'delete' run_delete else fail "Unknown command encountered" end end
Private Instance Methods
fail_if_lone_node_pool()
click to toggle source
# File lib/seira/node_pools.rb, line 177 def fail_if_lone_node_pool return if node_pools.count > 1 puts "Operation is unsafe to run with only one node pool. Please add a new node pool first to ensure services in cluster can continue running." exit(1) end
node_pools()
click to toggle source
TODO: Represent by a ruby object?
# File lib/seira/node_pools.rb, line 169 def node_pools JSON.parse(gcloud("container node-pools list --cluster #{context[:cluster]} --region=#{context[:region]}", context: context, format: :json)) end
nodes_for_pool(pool_name)
click to toggle source
# File lib/seira/node_pools.rb, line 173 def nodes_for_pool(pool_name) kubectl("get nodes -l cloud.google.com/gke-nodepool=#{pool_name} -o name", context: :none, return_output: true).split("\n") end
run_add()
click to toggle source
# File lib/seira/node_pools.rb, line 68 def run_add new_pool_name = args.shift disk_size = nil image_type = nil machine_type = nil service_account = nil num_nodes = nil args.each do |arg| if arg.start_with? '--copy=' node_pool_name_to_copy = arg.split('=')[1] node_pool_to_copy = node_pools.find { |p| p['name'] == node_pool_name_to_copy } fail "Could not find node pool with name #{node_pool_name_to_copy} to copy from." if node_pool_to_copy.nil? disk_size = node_pool_to_copy['config']['diskSizeGb'] image_type = node_pool_to_copy['config']['imageType'] machine_type = node_pool_to_copy['config']['machineType'] service_account = node_pool_to_copy['serviceAccount'] num_nodes = nodes_for_pool(node_pool_name_to_copy).count else puts "Warning: Unrecognized argument '#{arg}'" end end command = "container node-pools create #{new_pool_name} \ --cluster=#{context[:cluster]} \ --disk-size=#{disk_size} \ --image-type=#{image_type} \ --machine-type=#{machine_type} \ --num-nodes=#{num_nodes} \ --service-account=#{service_account}" if gcloud(command, conext: context, format: :boolean) puts 'New pool created successfully' else puts 'Failed to create new pool' exit(1) end end
run_cordon()
click to toggle source
# File lib/seira/node_pools.rb, line 110 def run_cordon fail_if_lone_node_pool node_pool_name = args.first nodes = nodes_for_pool(node_pool_name) nodes.each do |node| unless kubectl("cordon #{node}", context: :none) puts "Failed to cordon node #{node}" exit(1) end end puts "Successfully cordoned node pool #{node_pool_name}. No new workloads will be placed on #{node_pool_name} nodes." end
run_delete()
click to toggle source
# File lib/seira/node_pools.rb, line 149 def run_delete fail_if_lone_node_pool node_pool_name = args.first puts "Running cordon and drain as a safety measure first. If you haven't run these yet, please do so separately before deleting this node pool." run_cordon run_drain exit(1) unless HighLine.agree "Node pool has successfully been cordoned and drained, and should be safe to delete. Continue deleting node pool #{node_pool_name}?" if gcloud("container node-pools delete #{node_pool_name} --cluster #{context[:cluster]} --region=#{context[:region]}", context: context, format: :boolean) puts 'Node pool deleted successfully' else puts 'Failed to delete old pool' exit(1) end end
run_drain()
click to toggle source
# File lib/seira/node_pools.rb, line 126 def run_drain fail_if_lone_node_pool node_pool_name = args.first nodes = nodes_for_pool(node_pool_name) nodes.each do |node| # --force deletes pods that aren't managed by a ReplicationController, Job, or DaemonSet, # which shouldn't be any besides manually created temp pods # --ignore-daemonsets prevents failing due to presence of DaemonSets, which cannot be moved # because they're tied to a specific node # --delete-local-data prevents failing due to presence of local data, which cannot be moved # but is bad practice to use for anything that can't be lost puts "Draining #{node}" unless kubectl("drain --force --ignore-daemonsets --delete-local-data #{node}", context: :none) puts "Failed to drain node #{node}" exit(1) end end puts "Successfully drained all nodes in node pool #{node_pool_name}. No pods are running on #{node_pool_name} nodes." end
run_help()
click to toggle source
# File lib/seira/node_pools.rb, line 45 def run_help puts SUMMARY puts "\n\n" puts "Possible actions:\n\n" puts "list: List the node pools for this cluster: `node-pools list`" puts "list-nodes: List the nodes in specified node pool: `node-pools list-nodes <node-pool-name>`" puts "add: Create a node pool. First arg is the name to use, and use --copy to specify the existing node pool to copy." puts " `node-pools add <node-pool-name> --copy=<existing-node-pool-name>`" puts "cordon: Cordon nodes in specified node pool: `node-pools cordon <node-pool-name>`" puts "drain: Drain all pods from specified node pool: `node-pools drain <node-pool-name>`" puts "delete: Delete a node pool. Will force-run cordon and drain, first: `node-pools delete <node-pool-name>`" end
run_list()
click to toggle source
TODO: Info about what is running on it? TODO: What information do we get in the json format we could include here?
# File lib/seira/node_pools.rb, line 60 def run_list gcloud("container node-pools list --cluster #{context[:cluster]} --region=#{context[:region]}", context: context, format: :boolean) end
run_list_nodes()
click to toggle source
# File lib/seira/node_pools.rb, line 64 def run_list_nodes puts nodes_for_pool(args.first) end