amazon-pricing 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -32,13 +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
+ puts "Region,Instance Type,Linux PPH,Windows PPH,Prepay 1 Year,Prepay 3 Year"
36
36
  pricing.regions.each do |region|
37
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}"
38
+ puts "#{region.name},on-demand,#{t.api_name},#{t.linux_price_per_hour},#{t.windows_price_per_hour},,,,"
39
39
  end
40
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}"
41
+ puts "#{region.name},#{t.usage_type},#{t.api_name},#{t.linux_price_per_hour_1_year},#{t.windows_price_per_hour_1_year},#{t.linux_price_per_hour_3_year},#{t.windows_price_per_hour_3_year}#{t.prepay_1_year},#{t.prepay_3_year}"
42
42
  end
43
43
  end
44
44
  end
@@ -66,28 +66,31 @@ module AwsPricing
66
66
 
67
67
  # Retrieves the EC2 on-demand instance pricing.
68
68
  def get_ec2_on_demand_instance_pricing
69
- res = fetch_url(EC2_BASE_URL + "on-demand-instances.json")
69
+ res = fetch_url(EC2_BASE_URL + "pricing-on-demand-instances.json")
70
70
  @version_ec2_on_demand_instance = res['vers']
71
71
  res['config']['regions'].each do |reg|
72
72
  region_name = reg['region']
73
73
  region = find_or_create_region(region_name)
74
74
  reg['instanceTypes'].each do |type|
75
75
  type['sizes'].each do |size|
76
- region.add_instance_type(:on_demand, InstanceType.new(region, type['type'], size))
76
+ region.add_or_update_instance_type(:on_demand, InstanceType.new(region, type['type'], size))
77
77
  end
78
78
  end
79
79
  end
80
80
  end
81
81
 
82
82
  def get_ec2_reserved_instance_pricing
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)
83
+ fetch_ec2_reserved_instance_pricing(EC2_BASE_URL + "ri-light-linux.json", :light, :linux)
84
+ fetch_ec2_reserved_instance_pricing(EC2_BASE_URL + "ri-light-mswin.json", :light, :windows)
85
+ fetch_ec2_reserved_instance_pricing(EC2_BASE_URL + "ri-medium-linux.json", :medium, :linux)
86
+ fetch_ec2_reserved_instance_pricing(EC2_BASE_URL + "ri-medium-mswin.json", :medium, :windows)
87
+ fetch_ec2_reserved_instance_pricing(EC2_BASE_URL + "ri-heavy-linux.json", :heavy, :linux)
88
+ fetch_ec2_reserved_instance_pricing(EC2_BASE_URL + "ri-heavy-mswin.json", :heavy, :windows)
86
89
  end
87
90
 
88
91
  # Retrieves the EC2 on-demand instance pricing.
89
92
  # reserved_usage_type = :light, :medium, :heavy
90
- def fetch_ec2_reserved_instance_pricing(url, reserved_usage_type)
93
+ def fetch_ec2_reserved_instance_pricing(url, reserved_usage_type, platform)
91
94
  res = fetch_url(url)
92
95
  @version_ec2_reserved_instance = res['vers']
93
96
  res['config']['regions'].each do |reg|
@@ -95,14 +98,14 @@ module AwsPricing
95
98
  region = find_or_create_region(region_name)
96
99
  reg['instanceTypes'].each do |type|
97
100
  type['sizes'].each do |size|
98
- region.add_instance_type(:reserved, ReservedInstanceType.new(region, type['type'], size, reserved_usage_type), reserved_usage_type)
101
+ region.add_or_update_instance_type(:reserved, ReservedInstanceType.new(region, type['type'], size, reserved_usage_type, platform), reserved_usage_type)
99
102
  end
100
103
  end
101
104
  end
102
105
  end
103
106
 
104
107
  def fetch_ec2_ebs_pricing
105
- res = fetch_url(EC2_BASE_URL + "ebs.json")
108
+ res = fetch_url(EC2_BASE_URL + "pricing-ebs.json")
106
109
  res["config"]["regions"].each do |ebs_types|
107
110
  region = get_region(ebs_types["region"])
108
111
  region.ebs_price = EbsPrice.new(region, ebs_types)
@@ -115,7 +118,7 @@ module AwsPricing
115
118
  JSON.parse(page.body)
116
119
  end
117
120
 
118
- EC2_BASE_URL = "http://aws.amazon.com/ec2/pricing/pricing-"
121
+ EC2_BASE_URL = "http://aws.amazon.com/ec2/pricing/"
119
122
 
120
123
  # Lookup allows us to map to AWS API region names
121
124
  @@Region_Lookup = {
@@ -49,6 +49,16 @@ module AwsPricing
49
49
  return @linux_price_per_hour != nil || @windows_price_per_hour != nil
50
50
  end
51
51
 
52
+ def is_reserved?
53
+ false
54
+ end
55
+
56
+ def update(instance_type)
57
+ # Due to new AWS json we have to make two passes through to populate an instance
58
+ @windows_price_per_hour = instance_type.windows_price_per_hour if @windows_price_per_hour.nil?
59
+ @linux_price_per_hour = instance_type.linux_price_per_hour if @linux_price_per_hour.nil?
60
+ end
61
+
52
62
  protected
53
63
 
54
64
  attr_accessor :size, :instance_type
@@ -52,19 +52,23 @@ module AwsPricing
52
52
 
53
53
  # instance_type = :on_demand or :reserved
54
54
  # reserved_usage_type = :light, :medium, :heavy
55
- def add_instance_type(type, instance_type, reserved_usage_type = :medium)
56
- raise "Instance type #{instance_type.api_name} in region #{@name} already exists" if get_instance_type(type, instance_type.api_name, reserved_usage_type)
57
- if type == :on_demand
58
- @_ec2_on_demand_instance_types[instance_type.api_name] = instance_type
59
- elsif type == :reserved
60
- case reserved_usage_type
61
- when :light
62
- @_ec2_reserved_instance_types_light[instance_type.api_name] = instance_type
63
- when :medium
64
- @_ec2_reserved_instance_types_medium[instance_type.api_name] = instance_type
65
- when :heavy
66
- @_ec2_reserved_instance_types_heavy[instance_type.api_name] = instance_type
55
+ def add_or_update_instance_type(type, instance_type, reserved_usage_type = :medium)
56
+ current = get_instance_type(type, instance_type.api_name, reserved_usage_type)
57
+ if current.nil?
58
+ if type == :on_demand
59
+ @_ec2_on_demand_instance_types[instance_type.api_name] = instance_type
60
+ elsif type == :reserved
61
+ case reserved_usage_type
62
+ when :light
63
+ @_ec2_reserved_instance_types_light[instance_type.api_name] = instance_type
64
+ when :medium
65
+ @_ec2_reserved_instance_types_medium[instance_type.api_name] = instance_type
66
+ when :heavy
67
+ @_ec2_reserved_instance_types_heavy[instance_type.api_name] = instance_type
68
+ end
67
69
  end
70
+ else
71
+ current.update(instance_type)
68
72
  end
69
73
  end
70
74
 
@@ -15,26 +15,61 @@ 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, :usage_type
18
+ attr_accessor :prepay_1_year, :prepay_3_year, :usage_type, :linux_price_per_hour_3_year, :windows_price_per_hour_3_year
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, usage_type)
23
+ def initialize(region, instance_type, json, usage_type, platform)
24
24
  super(region, instance_type, json)
25
25
 
26
26
  # Fixme: calling twice, fix later
27
- values = get_values(json)
28
-
29
- @prepay_1_year = values['yrTerm1'].to_f unless values['yrTerm1'].to_f == 0
30
- @prepay_3_year = values['yrTerm3'].to_f unless values['yrTerm3'].to_f == 0
27
+ json['valueColumns'].each do |val|
28
+ case val["name"]
29
+ when "yrTerm1"
30
+ @prepay_1_year = val['prices']['USD'].to_f unless val['prices']['USD'].to_f == 0
31
+ when "yrTerm1Hourly"
32
+ if platform == :windows
33
+ @windows_price_per_hour = val['prices']['USD']
34
+ elsif platform == :linux
35
+ @linux_price_per_hour = val['prices']['USD']
36
+ end
37
+ when "yrTerm3"
38
+ @prepay_3_year = val['prices']['USD'].to_f unless val['prices']['USD'].to_f == 0
39
+ when "yrTerm3Hourly"
40
+ if platform == :windows
41
+ @windows_price_per_hour_3_year = val['prices']['USD']
42
+ elsif platform == :linux
43
+ @linux_price_per_hour_3_year = val['prices']['USD']
44
+ end
45
+ end
46
+ end
31
47
  @usage_type = usage_type
32
48
  end
33
49
 
50
+ def linux_price_per_hour_1_year
51
+ self.linux_price_per_hour
52
+ end
53
+
54
+ def windows_price_per_hour_1_year
55
+ self.windows_price_per_hour
56
+ end
57
+
34
58
  def to_s
35
59
  "Reserved Instance Type: #{@region.name} #{@api_name}, 1 Year Prepay=#{@prepay_1_year}, 3 Year Prepay=#{@prepay_3_year}, Linux=$#{@linux_price_per_hour}/hour, Windows=$#{@windows_price_per_hour}/hour"
36
60
  end
37
61
 
62
+ def is_reserved?
63
+ true
64
+ end
65
+
66
+ def update(instance_type)
67
+ super
68
+ # Due to new AWS json we have to make two passes through to populate an instance
69
+ @linux_price_per_hour_3_year = instance_type.linux_price_per_hour_3_year if @linux_price_per_hour_3_year.nil?
70
+ @windows_price_per_hour_3_year = instance_type.windows_price_per_hour_3_year if @windows_price_per_hour_3_year.nil?
71
+ end
72
+
38
73
  protected
39
74
  attr_accessor :size, :instance_type
40
75
 
@@ -47,20 +82,22 @@ module AwsPricing
47
82
  end
48
83
 
49
84
  @@Api_Name_Lookup_Reserved = {
50
- 'stdResI' => {'sm' => 'm1.small', 'lg' => 'm1.large', 'xl' => 'm1.xlarge'},
85
+ 'stdResI' => {'sm' => 'm1.small', 'med' => 'm1.medium', 'lg' => 'm1.large', 'xl' => 'm1.xlarge'},
51
86
  'hiMemResI' => {'xl' => 'm2.xlarge', 'xxl' => 'm2.2xlarge', 'xxxxl' => 'm2.4xlarge'},
52
87
  'hiCPUResI' => {'med' => 'c1.medium', 'xl' => 'c1.xlarge'},
53
88
  'clusterGPUResI' => {'xxxxl' => 'cg1.4xlarge'},
54
89
  'clusterCompResI' => {'xxxxl' => 'cc1.4xlarge', 'xxxxxxxxl' => 'cc2.8xlarge'},
55
90
  'uResI' => {'u' => 't1.micro'},
91
+ 'hiIoResI' => {'xxxxl' => 'hi1.4xlarge'},
56
92
  }
57
93
  @@Name_Lookup_Reserved = {
58
- 'stdResI' => {'sm' => 'Standard Small', 'lg' => 'Standard Large', 'xl' => 'Standard Extra Large'},
94
+ 'stdResI' => {'sm' => 'Standard Small', 'med' => 'Standard Medium', 'lg' => 'Standard Large', 'xl' => 'Standard Extra Large'},
59
95
  'hiMemResI' => {'xl' => 'Hi-Memory Extra Large', 'xxl' => 'Hi-Memory Double Extra Large', 'xxxxl' => 'Hi-Memory Quadruple Extra Large'},
60
96
  'hiCPUResI' => {'med' => 'High-CPU Medium', 'xl' => 'High-CPU Extra Large'},
61
97
  'clusterGPUResI' => {'xxxxl' => 'Cluster GPU Quadruple Extra Large'},
62
98
  'clusterCompResI' => {'xxxxl' => 'Cluster Compute Quadruple Extra Large', 'xxxxxxxxl' => 'Cluster Compute Eight Extra Large'},
63
99
  'uResI' => {'u' => 'Micro'},
100
+ 'hiIoResI' => {'xxxxl' => 'High I/O Quadruple Extra Large Instance'},
64
101
  }
65
102
  end
66
103
 
@@ -8,5 +8,5 @@
8
8
  # Home:: http://github.com/sonian/amazon-pricing
9
9
  #++
10
10
  module AwsPricing
11
- VERSION = '0.0.9'
11
+ VERSION = '0.1.0'
12
12
  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: 13
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 9
10
- version: 0.0.9
10
+ version: 0.1.0
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-13 00:00:00 -04:00
18
+ date: 2012-10-21 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies: []
21
21