poolparty 1.4.4 → 1.4.5

Sign up to get free protection for your applications and to get access to all the features.
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