class EksCli::NodeGroup

Constants

AMIS
CAPABILITIES
EKS_IAM_POLICIES
GPU_AMIS
T

Public Class Methods

new(cluster_name, name) click to toggle source
# File lib/eks_cli/nodegroup.rb, line 50
def initialize(cluster_name, name)
  @cluster_name = cluster_name
  @name = name
  @group = Config[cluster_name].for_group(name)
end

Public Instance Methods

asg() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 81
def asg
  @asg ||= cf_stack.resource("NodeGroup")
end
cf_stack() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 102
def cf_stack
  CloudFormation::Stack.find(@cluster_name, stack_name)
rescue Aws::CloudFormation::Errors::ValidationError => e
  Log.error("could not find stack for nodegroup #{@name} - please make sure to run eks create-nodegroup --all --yes -c <cluster_name> to sync config")
  raise e
end
create(wait_for_completion: true) click to toggle source
# File lib/eks_cli/nodegroup.rb, line 56
def create(wait_for_completion: true)
  Log.info "creating stack for nodegroup #{@group["group_name"]}"
  stack = CloudFormation::Stack.create(@cluster_name, cloudformation_config)
  Log.info "stack created - #{@group["group_name"]} - #{stack.id}"
  if wait_for_completion
    await(stack)
  end
  stack
end
delete() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 73
def delete
  Log.info "deleting nodegroup #{@name}"
  cf_stack.delete
  if @group["spotinst"]
    spotinst.delete_elastigroup(@group["spotinst"]["id"])
  end
end
export_to_spotinst(exact_instance_type) click to toggle source
# File lib/eks_cli/nodegroup.rb, line 89
def export_to_spotinst(exact_instance_type)
  Log.info "exporting nodegroup #{@name} to spotinst"
  instance_types = exact_instance_type ? [instance_type] : nil
  response = spotinst.import_asg(config["region"], asg, instance_types)
  if response.code == 200
    Log.info "Successfully created elastigroup"
    elastigroup = response.parsed_response["response"]["items"].first
    config.update_nodegroup({"group_name" => @name, "spotinst" => elastigroup})
  else
    Log.warn "Error creating elastigroup:\n #{response}"
  end
end
instance_type() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 85
def instance_type
  @group["instance_type"]
end
name() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 66
def name; @name; end
scale(min, max, asg = true, spotinst = false) click to toggle source
# File lib/eks_cli/nodegroup.rb, line 109
def scale(min, max, asg = true, spotinst = false)
  scale_asg(min, max) if asg
  scale_spotinst(min, max) if spotinst
end
tags() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 68
def tags
  [{key: "eks-nodegroup", value: @group["group_name"]},
   {key: "eks-cluster", value: @cluster_name}]
end

Private Instance Methods

add_bootstrap_args(group) click to toggle source
# File lib/eks_cli/nodegroup.rb, line 189
def add_bootstrap_args(group)
  group["bootstrap_args"] = base
  group.except("taints")
end
asg_client() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 217
def asg_client
  @asg_client ||= Aws::AutoScaling::Client.new(region: config["region"])
end
await(stack) click to toggle source
# File lib/eks_cli/nodegroup.rb, line 138
def await(stack)

  while stack.pending? do
    Log.info "waiting for stack #{stack.id} - status is #{stack.status}"
    sleep 10
  end

  Log.info "stack completed with status #{stack.status}"

  K8s::Auth.new(@cluster_name).update
end
bootstrap_args() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 179
def bootstrap_args
  kubelet_flags = "--node-labels=kubernetes.io/role=node,eks/node-group=#{@group["group_name"].downcase}"
  if taints = @group["taints"]
    kubelet_flags = "#{kubelet_flags} --register-with-taints=#{taints}"
  end
  flags = "--kubelet-extra-args \"#{kubelet_flags}\"" 
  flags = "#{flags} --enable-docker-bridge true" if @group["enable_docker_bridge"]
  flags
end
build_param(k, v) click to toggle source
# File lib/eks_cli/nodegroup.rb, line 194
def build_param(k, v)
  if key = T[k.to_sym]
    {parameter_key: key,
     parameter_value: v.to_s}
  end
end
build_params() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 162
def build_params
  @group["bootstrap_args"] = bootstrap_args
  @group["ami"] ||= default_ami
  @group["iam_policies"] = iam_policies
  @group.inject([]) do |params, (k, v)|
    if param = build_param(k, v)
      params << param
    else
      params
    end
  end
end
cf_template_body() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 134
def cf_template_body
  @cf_template_body ||= File.read(File.join($root_dir, '/assets/cf/nodegroup.yaml'))
end
cloudformation_config() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 150
def cloudformation_config
  {stack_name: stack_name,
   template_body: cf_template_body,
   parameters: build_params,
   capabilities: CAPABILITIES,
   tags: tags}
end
config() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 213
def config
  Config[@cluster_name]
end
default_ami() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 201
def default_ami
  if gpu?
    GPU_AMIS[config["kubernetes_version"]][config["region"]]
  else
    AMIS[config["kubernetes_version"]][config["region"]]
  end
end
gpu?() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 209
def gpu?
  @group["instance_type"].start_with?("p2.") || @group["instance_type"].start_with?("p3.")
end
iam_policies() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 175
def iam_policies
  (EKS_IAM_POLICIES + (config["iam_policies"] || [])).map {|p| "arn:aws:iam::aws:policy/#{p}"}.join(",")
end
scale_asg(min, max) click to toggle source
# File lib/eks_cli/nodegroup.rb, line 124
def scale_asg(min, max)
  Log.info "scaling ASG #{asg}: min -> #{min}, max -> #{max}"
  Log.info asg_client.update_auto_scaling_group({
    auto_scaling_group_name: asg, 
    max_size: max, 
    min_size: min
  })

end
scale_spotinst(min, max) click to toggle source
# File lib/eks_cli/nodegroup.rb, line 116
def scale_spotinst(min, max)
  if eid = @group.dig("spotinst", "id")
    spotinst.scale(eid, min, max)
  else
    Log.warn "could not find spotinst elastigroup for nodegroup #{@name}"
  end
end
spotinst() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 221
def spotinst
  @spotinst ||= Spotinst::Client.new
end
stack_name() click to toggle source
# File lib/eks_cli/nodegroup.rb, line 158
def stack_name
  "#{@group["cluster_name"]}-NodeGroup-#{@group["group_name"]}"
end