Module: GClouder::Resources::Container::NodePools::NodePool

Includes:
Config::CLIArgs, GCloud, Helpers, Logging, Shell
Defined in:
lib/gclouder/resources/container/node_pools.rb

Class Method Summary collapse

Methods included from Helpers

#hash_to_args, included, #module_exists?, #to_arg, #to_deep_merge_hash, #valid_json?

Methods included from GCloud

#gcloud, included, #verify

Methods included from Config::CLIArgs

check, #cli_args, cli_args, included, load, valid_resources

Methods included from Config::Project

load, #project, project

Methods included from Logging

#add, #bad, #change, #debug, #error, #fatal, #good, included, #info, log, loggers, #remove, report, #resource_state, setup, #warn, #warning

Methods included from Shell

included, #shell

Class Method Details

.autoscale(cluster, pool) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/gclouder/resources/container/node_pools.rb', line 175

def self.autoscale(cluster, pool)
  return if !pool["enable_autoscaling"]

  if !check_exists?(cluster["name"], pool["name"], pool["zone"])
    info "skipping autoscale for non-existant cluster/nodepool: #{cluster["name"]}/#{pool["name"]}", indent: 5
    return
  end

  autoscaling = gcloud("container node-pools list --cluster #{cluster["name"]} --zone #{cluster["zone"]} | jq '.[] | select(.name == \"#{pool["name"]}\") | .autoscaling'", force: true)

  if !autoscaling.key?("minNodeCount")
    autoscaling["minNodeCount"] = 0
  end

  if pool["min_nodes"] != autoscaling["minNodeCount"] or pool["max_nodes"] != autoscaling["maxNodeCount"]
    config = pool.context(:autoscale_cluster)
    parameters = hash_to_args(config)

    add "Updating autoscale constraints: Min: #{autoscaling["minNodeCount"]} -> #{pool["min_nodes"]} : Max: #{autoscaling["maxNodeCount"]} -> #{pool["max_nodes"]}", indent: 5
    gcloud("container clusters update #{cluster["name"]} --node-pool #{pool["name"]} #{parameters} --zone #{cluster["zone"]}")
  else
    true
  end
end

.calculate_number_of_zones(pool) ⇒ Object



200
201
202
# File 'lib/gclouder/resources/container/node_pools.rb', line 200

def self.calculate_number_of_zones(pool)
  pool.key?("additional_zones") ? (pool["additional_zones"].count + 1) : 1
end

.check_exists?(cluster_name, nodepool, zone) ⇒ Boolean

Returns:



213
214
215
# File 'lib/gclouder/resources/container/node_pools.rb', line 213

def self.check_exists?(cluster_name, nodepool, zone)
  gcloud("--format json container node-pools list --zone #{zone} --cluster #{cluster_name} | jq 'select(.[].name == \"#{nodepool}\") | length'", force: true).to_i.nonzero?
end

.create(cluster, pool) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/gclouder/resources/container/node_pools.rb', line 129

def self.create(cluster, pool)
  parameters = hash_to_args(pool.context(:create_nodepool))
  zone = pool["zone"]

  if !check_exists?(cluster["name"], pool["name"], zone)
    gcloud("container node-pools create --cluster #{cluster["name"]} #{parameters} #{pool["name"]}")
    if cli_args[:dry_run]
      add pool["name"], indent: 4
    else
      sleep 1 until check_exists?(cluster["name"], pool["name"], zone)
    end
  else
    good "#{pool["name"]}", indent: 4
  end
end

.remote_size(cluster_name, pool_name, zone) ⇒ Object



204
205
206
207
208
209
210
211
# File 'lib/gclouder/resources/container/node_pools.rb', line 204

def self.remote_size(cluster_name, pool_name, zone)
  remote_pool_config = gcloud("--format json container clusters describe #{cluster_name} --zone #{zone} | jq --join-output -c '.nodePools[] | select(.name == \"#{pool_name}\")'", force: true)
  instance_group_ids = remote_pool_config["instanceGroupUrls"].map { |url| data = url.split("/"); [ data[-1], data[-3] ] }.to_h
  nodes = instance_group_ids.map do |instance_group_id, zone|
    gcloud("--format json compute instance-groups describe --zone #{zone} #{instance_group_id} | jq '.size'", force: true).to_i
  end
  nodes.inject(0) { |sum, i| sum + i }
end

.resize(cluster, pool) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/gclouder/resources/container/node_pools.rb', line 145

def self.resize(cluster, pool)
  return if !pool["num_nodes"] or pool["enable_autoscaling"]
  config = pool.context(:resize_cluster)
  zone = pool["zone"]

  if !check_exists?(cluster["name"], pool["name"], zone)
    info "skipping resize for non-existant cluster/nodepool: #{cluster["name"]}/#{pool["name"]}", indent: 5
    return
  end

  number_of_zones = calculate_number_of_zones(pool)

  parameters = hash_to_args(config)

  current_size = remote_size(cluster["name"], pool["name"], pool["zone"])

  desired_size = if pool.key?("additional_zones")
    config["size"] * number_of_zones
  else
    config["size"]
  end

  if desired_size != current_size
    add "resizing pool (zones: #{number_of_zones}): #{current_size} -> #{desired_size}", indent: 5
    gcloud("container clusters resize #{cluster["name"]} --node-pool #{pool["name"]} #{parameters}")
  else
    true
  end
end