amazon-pricing 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -32,15 +32,13 @@ desc "Prints current EC2 pricing to console"
32
32
  task :print_price_list do
33
33
  require 'lib/amazon-pricing'
34
34
  pricing = AwsPricing::PriceList.new
35
+ puts "Region,Instance Type,Linux PPH,Windows PPH"
35
36
  pricing.regions.each do |region|
36
- puts "Region: #{region.name}"
37
- puts " On-demand instances"
38
- region.ec2_on_demand_instance_types.each do |instance_type|
39
- puts " #{instance_type.to_s}"
37
+ region.ec2_on_demand_instance_types.each do |t|
38
+ puts "#{region.name},on-demand,#{t.api_name},#{t.linux_price_per_hour},#{t.windows_price_per_hour}"
40
39
  end
41
- puts " Reserved instances"
42
- region.ec2_reserved_instance_types.each do |instance_type|
43
- puts " #{instance_type.to_s}"
40
+ region.ec2_reserved_instance_types.each do |t|
41
+ puts "#{region.name},#{t.usage_type},#{t.api_name},#{t.linux_price_per_hour},#{t.windows_price_per_hour}"
44
42
  end
45
43
  end
46
44
  end
@@ -26,6 +26,7 @@ module AwsPricing
26
26
  @_regions = {}
27
27
  get_ec2_on_demand_instance_pricing
28
28
  get_ec2_reserved_instance_pricing
29
+ fetch_ec2_ebs_pricing
29
30
  end
30
31
 
31
32
  def get_region(name)
@@ -38,10 +39,9 @@ module AwsPricing
38
39
 
39
40
  # Type = :on_demand or :reserved
40
41
  # reserved_usage_type = :light, :medium, :heavy
41
- def get_instance_type(availability_zone, type, api_name, reserved_usage_type = :medium)
42
- region_name = @@Availability_Zone_Lookup[availability_zone]
43
- raise "Region not found for availability zone #{availability_zone}" if region_name.nil?
42
+ def get_instance_type(region_name, type, api_name, reserved_usage_type = :medium)
44
43
  region = get_region(region_name)
44
+ raise "Region #{region_name} not found" if region.nil?
45
45
  region.get_instance_type(type, api_name, reserved_usage_type)
46
46
  end
47
47
 
@@ -66,9 +66,7 @@ module AwsPricing
66
66
 
67
67
  # Retrieves the EC2 on-demand instance pricing.
68
68
  def get_ec2_on_demand_instance_pricing
69
- uri = URI.parse(EC2_STANDARD_INSTANCE_PRICING_URL)
70
- page = Net::HTTP.get_response(uri)
71
- res = JSON.parse(page.body)
69
+ res = fetch_url(EC2_BASE_URL + "on-demand-instances.json")
72
70
  @version_ec2_on_demand_instance = res['vers']
73
71
  res['config']['regions'].each do |reg|
74
72
  region_name = reg['region']
@@ -82,51 +80,51 @@ module AwsPricing
82
80
  end
83
81
 
84
82
  def get_ec2_reserved_instance_pricing
85
- fetch_ec2_reserved_instance_pricing(EC2_RESERVED_INSTANCE_LIGHT_PRICING_URL, :light)
86
- fetch_ec2_reserved_instance_pricing(EC2_RESERVED_INSTANCE_MEDIUM_PRICING_URL, :medium)
87
- fetch_ec2_reserved_instance_pricing(EC2_RESERVED_INSTANCE_HEAVY_PRICING_URL, :heavy)
83
+ fetch_ec2_reserved_instance_pricing(EC2_BASE_URL + "reserved-instances-low-utilization.json", :light)
84
+ fetch_ec2_reserved_instance_pricing(EC2_BASE_URL + "reserved-instances.json", :medium)
85
+ fetch_ec2_reserved_instance_pricing(EC2_BASE_URL + "reserved-instances-high-utilization.json", :heavy)
88
86
  end
89
87
 
90
88
  # Retrieves the EC2 on-demand instance pricing.
91
89
  # reserved_usage_type = :light, :medium, :heavy
92
90
  def fetch_ec2_reserved_instance_pricing(url, reserved_usage_type)
93
- uri = URI.parse(url)
94
- page = Net::HTTP.get_response(uri)
95
- res = JSON.parse(page.body)
91
+ res = fetch_url(url)
96
92
  @version_ec2_reserved_instance = res['vers']
97
93
  res['config']['regions'].each do |reg|
98
94
  region_name = reg['region']
99
95
  region = find_or_create_region(region_name)
100
96
  reg['instanceTypes'].each do |type|
101
97
  type['sizes'].each do |size|
102
- region.add_instance_type(:reserved, ReservedInstanceType.new(region, type['type'], size), reserved_usage_type)
98
+ region.add_instance_type(:reserved, ReservedInstanceType.new(region, type['type'], size, reserved_usage_type), reserved_usage_type)
103
99
  end
104
100
  end
105
101
  end
106
102
  end
107
103
 
108
- EC2_STANDARD_INSTANCE_PRICING_URL = 'http://aws.amazon.com/ec2/pricing/pricing-on-demand-instances.json'
109
- EC2_RESERVED_INSTANCE_LIGHT_PRICING_URL = 'http://aws.amazon.com/ec2/pricing/pricing-reserved-instances-low-utilization.json'
110
- EC2_RESERVED_INSTANCE_MEDIUM_PRICING_URL = 'http://aws.amazon.com/ec2/pricing/pricing-reserved-instances.json'
111
- EC2_RESERVED_INSTANCE_HEAVY_PRICING_URL = 'http://aws.amazon.com/ec2/pricing/pricing-reserved-instances-high-utilization.json'
112
-
113
- @@Availability_Zone_Lookup = {
114
- 'us-east-1a' => 'us-east', 'us-east-1b' => 'us-east', 'us-east-1c' => 'us-east',
115
- 'us-east-1d' => 'us-east', 'us-east-1e' => 'us-east', 'us-west-1a' => 'us-west',
116
- 'us-west-1b' => 'us-west', 'us-west-1c' => 'us-west', 'us-west-2a' => 'us-west-2',
117
- 'us-west-2b' => 'us-west-2', 'eu-west-1a' => 'eu-ireland', 'eu-west-1b' => 'eu-ireland',
118
- 'eu-west-1c' => 'eu-ireland', 'ap-southeast-1a' => 'apac-sin', 'ap-southeast-1b' => 'apac-sin',
119
- 'ap-northeast-1a' => 'apac-tokyo', 'ap-northeast-1b' => 'apac-tokyo', 'sa-east-1a' => 'sa-east-1',
120
- 'sa-east-1b' => 'sa-east-1'
121
- }
122
-
104
+ def fetch_ec2_ebs_pricing
105
+ res = fetch_url(EC2_BASE_URL + "ebs.json")
106
+ res["config"]["regions"].each do |ebs_types|
107
+ region = get_region(ebs_types["region"])
108
+ region.ebs_price = EbsPrice.new(region, ebs_types)
109
+ end
110
+ end
111
+
112
+ def fetch_url(url)
113
+ uri = URI.parse(url)
114
+ page = Net::HTTP.get_response(uri)
115
+ JSON.parse(page.body)
116
+ end
117
+
118
+ EC2_BASE_URL = "http://aws.amazon.com/ec2/pricing/pricing-"
119
+
120
+ # Lookup allows us to map to AWS API region names
123
121
  @@Region_Lookup = {
124
122
  'us-east-1' => 'us-east',
125
123
  'us-west-1' => 'us-west',
126
124
  'us-west-2' => 'us-west-2',
127
125
  'eu-west-1' => 'eu-ireland',
128
- 'ap-southeast-1' => 'apac-sin',
129
- 'ap-northeast-1' => 'apac-tokyo',
126
+ 'ap-southeast-1' => 'apac-sin',
127
+ 'ap-northeast-1' => 'apac-tokyo',
130
128
  'sa-east-1' => 'sa-east-1'
131
129
  }
132
130
  end
@@ -0,0 +1,32 @@
1
+ #--
2
+ # Amazon Web Services Pricing Ruby library
3
+ #
4
+ # Ruby Gem Name:: amazon-pricing
5
+ # Author:: Joe Kinsella (mailto:joe.kinsella@gmail.com)
6
+ # Copyright:: Copyright (c) 2011-2012 Sonian
7
+ # License:: Distributes under the same terms as Ruby
8
+ # Home:: http://github.com/sonian/amazon-pricing
9
+ #++
10
+ module AwsPricing
11
+
12
+ class EbsPrice
13
+ attr_reader :standard_per_gb, :standard_per_million_io,
14
+ :preferred_per_gb, :preferred_per_iops, :s3_snaps_per_gb
15
+
16
+ def initialize(region, json)
17
+ json["types"].each do |t|
18
+ case t["name"]
19
+ when "ebsVols"
20
+ @standard_per_gb = t["values"].select{|v| v["rate"] == "perGBmoProvStorage" }.first["prices"].values.first.to_f
21
+ @standard_per_million_io = t["values"].select{|v| v["rate"] == "perMMIOreq" }.first["prices"].values.first.to_f
22
+ when "ebsPIOPSVols"
23
+ @preferred_per_gb = t["values"].select{|v| v["rate"] == "perGBmoProvStorage" }.first["prices"].values.first.to_f
24
+ @preferred_per_iops = t["values"].select{|v| v["rate"] == "perPIOPSreq" }.first["prices"].values.first.to_f
25
+ when "ebsSnapsToS3"
26
+ @s3_snaps_per_gb = t["values"].select{|v| v["rate"] == "perGBmoDataStored" }.first["prices"].values.first.to_f
27
+ end
28
+ end
29
+ end
30
+
31
+ end
32
+ end
@@ -16,7 +16,7 @@ module AwsPricing
16
16
  # $0.48/hour for Windows.
17
17
  #
18
18
  class InstanceType
19
- attr_accessor :region, :name, :api_name, :linux_price_per_hour, :windows_price_per_hour,
19
+ attr_accessor :name, :api_name, :linux_price_per_hour, :windows_price_per_hour,
20
20
  :memory_in_mb, :disk_in_mb, :platform, :compute_units
21
21
 
22
22
  # Initializes and InstanceType object given a region, the internal
@@ -25,7 +25,6 @@ module AwsPricing
25
25
  def initialize(region, instance_type, json)
26
26
  values = get_values(json)
27
27
 
28
- @region = region
29
28
  @size = json['size']
30
29
  @linux_price_per_hour = values['linux'].to_f
31
30
  @linux_price_per_hour = nil if @linux_price_per_hour == 0
@@ -50,10 +49,6 @@ module AwsPricing
50
49
  return @linux_price_per_hour != nil || @windows_price_per_hour != nil
51
50
  end
52
51
 
53
- def to_s
54
- "Instance Type: #{@region.name} #{@api_name}, Linux=$#{@linux_price_per_hour}/hour, Windows=$#{@windows_price_per_hour}/hour"
55
- end
56
-
57
52
  protected
58
53
 
59
54
  attr_accessor :size, :instance_type
@@ -15,7 +15,7 @@ module AwsPricing
15
15
  # e.g. us-east, us-west
16
16
  #
17
17
  class Region
18
- attr_accessor :name
18
+ attr_accessor :name, :ebs_price
19
19
 
20
20
  def initialize(name)
21
21
  @name = name
@@ -39,7 +39,7 @@ module AwsPricing
39
39
  when :heavy
40
40
  @_ec2_reserved_instance_types_heavy.values
41
41
  else
42
- @_ec2_reserved_instance_types_light.values << @_ec2_reserved_instance_types_medium.values << @_ec2_reserved_instance_types_heavy.values
42
+ @_ec2_reserved_instance_types_light.values + @_ec2_reserved_instance_types_medium.values + @_ec2_reserved_instance_types_heavy.values
43
43
  end
44
44
  end
45
45
 
@@ -15,12 +15,12 @@ module AwsPricing
15
15
  # reserved instances have three usage types: light, medium and heavy.
16
16
  #
17
17
  class ReservedInstanceType < InstanceType
18
- attr_accessor :prepay_1_year, :prepay_3_year
18
+ attr_accessor :prepay_1_year, :prepay_3_year, :usage_type
19
19
 
20
20
  # Initializes and InstanceType object given a region, the internal
21
21
  # type (e.g. stdODI) and the json for the specific instance. The json is
22
22
  # based on the current undocumented AWS pricing API.
23
- def initialize(region, instance_type, json)
23
+ def initialize(region, instance_type, json, usage_type)
24
24
  super(region, instance_type, json)
25
25
 
26
26
  # Fixme: calling twice, fix later
@@ -28,6 +28,7 @@ module AwsPricing
28
28
 
29
29
  @prepay_1_year = values['yrTerm1'].to_f unless values['yrTerm1'].to_f == 0
30
30
  @prepay_3_year = values['yrTerm3'].to_f unless values['yrTerm3'].to_f == 0
31
+ @usage_type = usage_type
31
32
  end
32
33
 
33
34
  def to_s
@@ -8,5 +8,5 @@
8
8
  # Home:: http://github.com/sonian/amazon-pricing
9
9
  #++
10
10
  module AwsPricing
11
- VERSION = '0.0.8'
11
+ VERSION = '0.0.9'
12
12
  end
@@ -16,8 +16,7 @@ require 'test/unit'
16
16
  class TestEc2InstanceTypes < Test::Unit::TestCase
17
17
  def test_cc8xlarge_issue
18
18
  pricing = AwsPricing::PriceList.new
19
- obj = pricing.get_instance_type('us-east-1d', :reserved, 'cc2.8xlarge', :medium)
20
- puts obj.inspect
19
+ obj = pricing.get_instance_type('us-east', :reserved, 'cc2.8xlarge', :medium)
21
20
  assert obj.api_name == 'cc2.8xlarge'
22
21
  end
23
22
 
@@ -69,4 +68,21 @@ class TestEc2InstanceTypes < Test::Unit::TestCase
69
68
  instance = region.get_instance_type(:on_demand, 'm1.large')
70
69
  assert instance.memory_in_mb == 7500
71
70
  end
71
+
72
+ def test_non_standard_region_name
73
+ pricing = AwsPricing::PriceList.new
74
+ region = pricing.get_region('eu-west-1')
75
+ instance = region.get_instance_type(:on_demand, 'm1.large')
76
+ assert instance.memory_in_mb == 7500
77
+ end
78
+
79
+ def test_ebs
80
+ pricing = AwsPricing::PriceList.new
81
+ region = pricing.get_region('us-east')
82
+ assert region.ebs_price.standard_per_gb == 0.10
83
+ assert region.ebs_price.standard_per_million_io == 0.10
84
+ assert region.ebs_price.preferred_per_gb == 0.125
85
+ assert region.ebs_price.preferred_per_iops == 0.10
86
+ assert region.ebs_price.s3_snaps_per_gb == 0.125
87
+ end
72
88
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amazon-pricing
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 13
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 8
10
- version: 0.0.8
9
+ - 9
10
+ version: 0.0.9
11
11
  platform: ruby
12
12
  authors:
13
13
  - Joe Kinsella
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-08-04 00:00:00 -04:00
18
+ date: 2012-08-13 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -36,6 +36,7 @@ files:
36
36
  - Rakefile
37
37
  - amazon-pricing.gemspec
38
38
  - lib/amazon-pricing.rb
39
+ - lib/amazon-pricing/ebs-price.rb
39
40
  - lib/amazon-pricing/instance-type.rb
40
41
  - lib/amazon-pricing/region.rb
41
42
  - lib/amazon-pricing/reserved-instance-type.rb