cucloud 0.7.5 → 0.7.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 34988a759221260aa910c03f3063f5dc833f5422
4
- data.tar.gz: b002d383d5a5766231643a6d9ec214e0c376396c
3
+ metadata.gz: b9c097b02b7b8ee93f6adb3be2c80ea3e859b767
4
+ data.tar.gz: 7e35d979d839416122e5b42a7805de6481afb2f5
5
5
  SHA512:
6
- metadata.gz: 359e34085a6474d24686dc2874ac878cea7856be6549afe3d542b35aeb7a8108ecdb2cd5d335f52ef8efbd945385ae1f601e36bd9cb49aa0030c4a2578ab88d9
7
- data.tar.gz: 9a9d44ee28bfe4572f0351afe87aea8f2868f013386e6832ec9e454a110ba1b0b84548ecc7235aa533d33ed24a4b38bd9a660dca899ce1df89f032bae539e506
6
+ metadata.gz: d2be8ee2db184cf7b875764c83ee0fc01820710741fe981ffb73c95d93cb4a42c0f29d4459d8f4a255127df4448de5b8321ad46a8d1fdd142a5522a2cccca49b
7
+ data.tar.gz: 5d91d37eaa27392c7420458bb97d43caffa9502667701b366606ba6c1431c1582428b6dce2317ecfa5fb5724b5ca3e2d8906b73fd79eda2f33e8a9a69101a4fc
data/cucloud.gemspec CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_dependency 'aws-sdk', '~> 2'
28
28
  spec.add_dependency 'uuid', '~> 2.3'
29
+ spec.add_dependency 'descriptive_statistics', '~> 2.5'
29
30
 
30
31
  spec.add_development_dependency 'bundler', '~> 1.11'
31
32
  spec.add_development_dependency 'coveralls'
data/lib/cucloud.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'aws-sdk'
2
+ require 'descriptive_statistics'
2
3
 
3
4
  # Main Cucloud Module namespace and defaults
4
5
  module Cucloud
@@ -15,6 +16,7 @@ module Cucloud
15
16
  require 'cucloud/rds_utils'
16
17
  require 'cucloud/lambda_utils'
17
18
  require 'cucloud/cfn_utils'
19
+ require 'cucloud/utilities'
18
20
 
19
21
  # This is the default region API calls are made against
20
22
  DEFAULT_REGION = 'us-east-1'.freeze
@@ -11,6 +11,10 @@ module Cucloud
11
11
  WAITER_MAX_ATTEMPS = 240
12
12
  # Delay between calls used by waiter to check status
13
13
  WAITER_DELAY = 15
14
+ # Two weeks in hours
15
+ TWO_WEEKS = 336
16
+ # Default OS to use
17
+ DEFAULT_OS = 'Linux/UNIX'.freeze
14
18
 
15
19
  def initialize(ec2_client = Aws::EC2::Client.new, ssm_utils = Cucloud::SSMUtils.new)
16
20
  @ec2 = ec2_client
@@ -195,7 +199,7 @@ module Cucloud
195
199
  next if volumes_backed_up_recently[volume.volume_id.to_s]
196
200
  instance_name = get_instance_name(volume.attachments[0].instance_id)
197
201
  tags = additional_snapshot_tags.dup
198
- unless tags.any? { |tagitem| tagitem[:key] == 'Instance Name' }
202
+ unless instance_name.nil? || tags.any? { |tagitem| tagitem[:key] == 'Instance Name' }
199
203
  tags << { key: 'Instance Name', value: instance_name }
200
204
  end
201
205
  volume.tags.each do |tag|
@@ -253,5 +257,64 @@ module Cucloud
253
257
  end
254
258
  found_snapshots
255
259
  end
260
+
261
+ # Get a recommendation for a spot bid request. Given an instance type and
262
+ # OS we will grab data from a period specified, default is from two weeks to now,
263
+ # and calculate recommendations for the AZs in the current region
264
+ # @param instance_type [String] Insrance type to get bid for
265
+ # @param os [String] OS you whish to run, default linux
266
+ # @param num_hours [Integer] How many hours to look back, default two weeks
267
+ # @return [Hash] Reccomendations by region, empty if no viable recommendations
268
+ def best_spot_bid_price(instance_type, os = DEFAULT_OS, num_hours = TWO_WEEKS)
269
+ price_history_by_az = {}
270
+ recommendations = {}
271
+
272
+ options = {
273
+ end_time: Time.now.utc,
274
+ instance_types: [
275
+ instance_type
276
+ ],
277
+ product_descriptions: [
278
+ os
279
+ ],
280
+ start_time: (Time.now - num_hours * 60).utc
281
+ }
282
+
283
+ loop do
284
+ price_history = @ec2.describe_spot_price_history(options)
285
+ price_history.spot_price_history.each do |price|
286
+ price_history_by_az[price.availability_zone] = [] unless price_history_by_az[price.availability_zone]
287
+ price_history_by_az[price.availability_zone].push(price.spot_price.to_f)
288
+ end
289
+
290
+ break if price_history.next_token.nil? || price_history.next_token.empty?
291
+ options[:next_token] = price_history.next_token
292
+ end
293
+
294
+ price_history_by_az.each do |key, data|
295
+ stats = data.descriptive_statistics
296
+ next unless stats[:number] > 30
297
+ confidence_interval = Cucloud::Utilities.confidence_interval_99(
298
+ stats[:mean],
299
+ stats[:standard_deviation],
300
+ stats[:number]
301
+ )
302
+ recommendations[key] = confidence_interval[1]
303
+ end
304
+
305
+ recommendations
306
+ end
307
+
308
+ # Make spot instance request
309
+ # @param options [Hash] Options to provide to the API
310
+ # see http://docs.aws.amazon.com/sdkforruby/api/Aws/EC2/Client.html#request_spot_instances-instance_method
311
+ # @return [Hash] Description of the spot request
312
+ def make_spot_instance_request(options)
313
+ spot_requests = @ec2.request_spot_instances(options)
314
+ request_ids = [spot_requests.spot_instance_requests[0].spot_instance_request_id]
315
+
316
+ @ec2.wait_until(:spot_instance_request_fulfilled, spot_instance_request_ids: request_ids)
317
+ @ec2.describe_spot_instance_requests(spot_instance_request_ids: request_ids)
318
+ end
256
319
  end
257
320
  end
@@ -0,0 +1,39 @@
1
+ module Cucloud
2
+ # Utilities class - for basice shared utilities
3
+ class Utilities
4
+ # Z Score to calculate 99% confidence interval
5
+ Z_SCORE_99 = 2.576
6
+ # Z Score to calculate 99% confidence interval
7
+ Z_SCORE_96 = 1.96
8
+
9
+ # Calculate 99% confidence interval
10
+ # @param mean [Float] sample mean
11
+ # @param stdev [Float] sample standard deviation
12
+ # @param sample_size [Integer] sample size
13
+ # @return [Array] Two element array representing the computed confidence interval
14
+ def self.confidence_interval_99(mean, stdev, sample_size)
15
+ confidence_interval(mean, stdev, sample_size, Z_SCORE_99)
16
+ end
17
+
18
+ # Calculate 95% confidence interval
19
+ # @param mean [Float] sample mean
20
+ # @param stdev [Float] sample standard deviation
21
+ # @param sample_size [Integer] sample size
22
+ # @return [Array] Two element array representing the computed confidence interval
23
+ def self.confidence_interval_95(mean, stdev, sample_size)
24
+ confidence_interval(mean, stdev, sample_size, Z_SCORE_96)
25
+ end
26
+
27
+ private_class_method
28
+
29
+ # Calculate confidence interval for given zscore
30
+ # @param mean [Float] sample mean
31
+ # @param stdev [Float] sample standard deviation
32
+ # @param sample_size [Integer] sample size
33
+ # @return [Array] Two element array representing the computed confidence interval
34
+ def self.confidence_interval(mean, stdev, sample_size, zscore)
35
+ delta = zscore * stdev / Math.sqrt(sample_size - 1)
36
+ [mean - delta, mean + delta]
37
+ end
38
+ end
39
+ end
@@ -1,5 +1,5 @@
1
1
  module Cucloud
2
2
  # Disable mutable constant warning - freezing this oddly breaks bundler
3
3
  # rubocop:disable Style/MutableConstant
4
- VERSION = '0.7.5'
4
+ VERSION = '0.7.6'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cucloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.5
4
+ version: 0.7.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - sbower
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2017-03-14 00:00:00.000000000 Z
13
+ date: 2017-04-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws-sdk
@@ -40,6 +40,20 @@ dependencies:
40
40
  - - "~>"
41
41
  - !ruby/object:Gem::Version
42
42
  version: '2.3'
43
+ - !ruby/object:Gem::Dependency
44
+ name: descriptive_statistics
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '2.5'
50
+ type: :runtime
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '2.5'
43
57
  - !ruby/object:Gem::Dependency
44
58
  name: bundler
45
59
  requirement: !ruby/object:Gem::Requirement
@@ -159,6 +173,7 @@ files:
159
173
  - lib/cucloud/lambda_utils.rb
160
174
  - lib/cucloud/rds_utils.rb
161
175
  - lib/cucloud/ssm_utils.rb
176
+ - lib/cucloud/utilities.rb
162
177
  - lib/cucloud/version.rb
163
178
  - lib/cucloud/vpc_utils.rb
164
179
  homepage: https://github.com/CU-CloudCollab/cucloud_ruby