poolparty 1.4.4 → 1.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -21,7 +21,9 @@ For instance, to start a basic cloud, let's write one:
21
21
  cloud "app" do
22
22
  instances 2..10
23
23
  using :ec2
24
- autscale
24
+ autoscale do
25
+ trigger :lower_threshold => 0.3, :upper_threshold => 1.0, :measure => :cpu
26
+ end
25
27
  security_group do
26
28
  authorize :from_port => 22, :to_port => 22
27
29
  end
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :minor: 4
3
- :patch: 4
3
+ :patch: 5
4
4
  :major: 1
5
5
  :build:
data/examples/simple.rb CHANGED
@@ -8,7 +8,9 @@ pool "poolparty" do
8
8
  cloud "simple" do
9
9
  instances 1..3
10
10
  using :ec2
11
- autoscale
11
+ autoscale do
12
+ trigger :lower_threshold => 0.3, :upper_threshold => 1.0, :measure => :cpu
13
+ end
12
14
  image_id "ami-ccf615a5" #alestic jaunty
13
15
  availability_zones ['us-east-1b']
14
16
  #TODO: accept array of hashes defining security group rules
@@ -87,7 +87,8 @@ module CloudProviders
87
87
  puts " minimum_instances: #{minimum_instances}"
88
88
  puts " maximum_instances: #{maximum_instances}"
89
89
  puts " security_groups: #{security_group_names.join(", ")}"
90
- puts " running on keypair: #{keypair}"
90
+ puts " using keypair: #{keypair}"
91
+ puts " user: #{user}\n"
91
92
 
92
93
  security_groups.each do |sg|
93
94
  sg.run
@@ -98,19 +99,19 @@ module CloudProviders
98
99
  puts " load balancer: #{lb.name}"
99
100
  lb.run
100
101
  end
101
- end
102
- if autoscalers.empty?
102
+ end
103
+
104
+ if autoscalers.empty? # not using autoscaling
103
105
  puts "---- live, running instances (#{nodes.size}) ----"
104
106
  if nodes.size < minimum_instances
105
107
  expansion_count = minimum_instances - nodes.size
106
- puts "-----> expanding the cloud because the minimum_instances is not satisified: #{expansion_count}"
108
+ puts "-----> expanding the cloud because the #{expansion_count} minimum_instances is not satisified: "
107
109
  expand_by(expansion_count)
108
110
  elsif nodes.size > maximum_instances
109
111
  contraction_count = nodes.size - maximum_instances
110
- puts "-----> contracting the cloud because the instances count exceeds the maximum_instances by #{contraction_count}"
112
+ puts "-----> contracting the cloud because the instances count exceeds the #{maximum_instances} maximum_instances by #{contraction_count}"
111
113
  contract_by(contraction_count)
112
114
  end
113
-
114
115
  progress_bar_until("Waiting for the instances to be launched") do
115
116
  reset!
116
117
  running_nodes = nodes.select {|n| n.running? }
@@ -170,12 +171,12 @@ module CloudProviders
170
171
  progress_bar_until("Waiting for node to launch...") do
171
172
  wait_for_node(e)
172
173
  end
173
- all_nodes.select {|n| n.instance_id == e.instance_id }.first
174
+ all_nodes.detect {|n| n.instance_id == e.instance_id }
174
175
  end
175
176
 
176
177
  def wait_for_node(instance)
177
178
  reset!
178
- inst = all_nodes.select {|n| n.instance_id == instance.instance_id }.first
179
+ inst = all_nodes.detect {|n| n.instance_id == instance.instance_id }
179
180
  inst.running?
180
181
  end
181
182
 
@@ -21,12 +21,18 @@ module CloudProviders
21
21
  puts "Deleting old launch configuration: #{old_launch_configuration_name}"
22
22
  as.delete_launch_configuration(:launch_configuration_name => old_launch_configuration_name)
23
23
  end
24
-
24
+ end
25
+
26
+ triggers.each do |trigger|
27
+ trigger.run
25
28
  end
26
29
  end
27
30
 
28
31
  # First, change the min_count to
29
32
  def teardown
33
+ triggers.each do |trigger|
34
+ trigger.teardown
35
+ end
30
36
  if autoscaling_groups.select {|n| n.name == name }.empty?
31
37
  puts "Cloud #{cloud.name} autoscaling group does not exist"
32
38
  else
@@ -292,7 +298,16 @@ module CloudProviders
292
298
  describe_autoscaling_groups.DescribeAutoScalingGroupsResult.AutoScalingGroups.member
293
299
  end
294
300
 
301
+ def trigger(*trigger_hashes)
302
+ trigger_hashes.each do |hsh, blk|
303
+ triggers << ElasticTrigger.new(name, hsh.merge(:cloud => cloud), &blk)
304
+ end
305
+ end
306
+
295
307
  private
308
+ def triggers
309
+ @triggers ||= []
310
+ end
296
311
  def reset!
297
312
  @old_auto_scaling_group_name =
298
313
  @new_auto_scaling_group_name =
@@ -301,4 +316,112 @@ module CloudProviders
301
316
  cloud.reset!
302
317
  end
303
318
  end
319
+ class ElasticTrigger < Ec2Helper
320
+ default_options(
321
+ :measure => :cpu,
322
+ :period => 60,
323
+ :statistic => :average,
324
+ :unit => "Seconds",
325
+ :lower_threshold => 20,
326
+ :upper_threshold => 60,
327
+ :trigger_name => "CpuTrigger",
328
+ :lower_breach_scale_increment => -1,
329
+ :upper_breach_scale_increment => 1,
330
+ :breach_duration => 120
331
+ )
332
+
333
+ def measure_names
334
+ {:cpu => "CPUUtilization"}
335
+ end
336
+
337
+ def statistic_names
338
+ {:min => "Minimum", :max => "Maximum", :average => "Average", :sum => "Sum"}
339
+ end
340
+
341
+ def run
342
+ if autoscaling_triggers.empty?
343
+ create_autoscaling_trigger!
344
+ else
345
+ t = autoscaling_triggers.map do |hsh|
346
+ diff(hsh)
347
+ end.flatten
348
+ unless t.empty?
349
+ puts "Creating or updating trigger: #{trigger_name}"
350
+ create_autoscaling_trigger!
351
+ end
352
+ end
353
+ end
354
+
355
+ def teardown
356
+ autoscaling_triggers.each do |trigger|
357
+ puts "Deleting trigger: #{trigger[:trigger_name]}"
358
+ as.delete_trigger(:trigger_name => trigger[:trigger_name], :autoscaling_group_name => name)
359
+ end
360
+ end
361
+
362
+ def diff(hsh={})
363
+ [ :measure_name,
364
+ :period,
365
+ :statistic,
366
+ :lower_threshold,
367
+ :lower_breach_scale_increment,
368
+ :upper_threshold,
369
+ :upper_breach_scale_increment,
370
+ :unit,
371
+ :trigger_name].reject do |k|
372
+ hsh[k].to_s.capitalize == self.send(k).to_s.capitalize
373
+ end
374
+ end
375
+
376
+ private
377
+
378
+ def autoscaling_triggers
379
+ begin
380
+ as.describe_triggers(:autoscaling_group_name => name).DescribeTriggersResult.Triggers.member.map do |trigger|
381
+ {
382
+ :trigger_name => trigger["TriggerName"],
383
+ :statistic => trigger["Statistic"],
384
+ :status => trigger["Status"],
385
+ :lower_threshold => trigger["LowerThreshold"],
386
+ :created_time => trigger["CreatedTime"],
387
+ :measure_name => trigger["MeasureName"],
388
+ :upper_threshold => trigger["UpperThreshold"],
389
+ :lower_breach_scale_increment => trigger["LowerBreachScaleIncrement"],
390
+ :period => trigger["Period"],
391
+ :upper_breach_scale_increment => trigger["UpperBreachScaleIncrement"],
392
+ :breach_duration => trigger["BreachDuration"],
393
+ :dimensions => trigger["Dimensions"],
394
+ :unit => trigger["Unit"],
395
+ :autoscaling_group_name => trigger["AutoScalingGroupName"]
396
+ }
397
+ end
398
+ rescue Exception => e
399
+ []
400
+ end
401
+ end
402
+ def create_autoscaling_trigger!
403
+ as.create_or_updated_scaling_trigger(
404
+ :autoscaling_group_name => name,
405
+ :dimensions => {:name => "AutoScalingGroupName", :value => name},
406
+ :measure_name => measure_name,
407
+ :period => "#{period}",
408
+ :trigger_name => trigger_name,
409
+ :statistic => (statistic_names[statistic] || statistic),
410
+ :unit => unit,
411
+ :breach_duration => breach_duration,
412
+ :lower_threshold => "#{lower_threshold}",
413
+ :lower_breach_scale_increment => "#{lower_breach_scale_increment}",
414
+ :upper_threshold => "#{upper_threshold}",
415
+ :upper_breach_scale_increment => "#{upper_breach_scale_increment}"
416
+ )
417
+ end
418
+
419
+ def measure_name
420
+ measure_names[measure] || measure
421
+ end
422
+
423
+ def trigger_name
424
+ "#{(measure_names[measure] || measure)}-#{name}" || name
425
+ end
426
+ end
304
427
  end
@@ -54,7 +54,7 @@ module CloudProviders
54
54
 
55
55
  def run_chef!
56
56
  ssh([
57
- "/var/lib/gems/1.8/bin/chef-solo -j /etc/chef/dna.json -c /etc/chef/solo.rb"
57
+ "chef-solo -j /etc/chef/dna.json -c /etc/chef/solo.rb"
58
58
  ])
59
59
  end
60
60
 
@@ -112,7 +112,7 @@ module AWS
112
112
  params["Dimensions.member.1.Name"] = options[:dimensions][:name]
113
113
  params["Dimensions.member.1.Value"] = options[:dimensions][:value]
114
114
  else
115
- raise ArgumentError, "Dimensionss must be either an array or a hash"
115
+ raise ArgumentError, "Dimensions must be either an array or a hash"
116
116
  end
117
117
  params['MeasureName'] = options[:measure_name]
118
118
  params['Statistic'] = options[:statistic]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: poolparty
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.4
4
+ version: 1.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ari Lerner