amazon-pricing 0.0.9 → 0.1.0
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/Rakefile +3 -3
- data/lib/amazon-pricing.rb +12 -9
- data/lib/amazon-pricing/instance-type.rb +10 -0
- data/lib/amazon-pricing/region.rb +16 -12
- data/lib/amazon-pricing/reserved-instance-type.rb +45 -8
- data/lib/amazon-pricing/version.rb +1 -1
- metadata +4 -4
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.
|
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
|
data/lib/amazon-pricing.rb
CHANGED
@@ -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.
|
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 + "
|
84
|
-
fetch_ec2_reserved_instance_pricing(EC2_BASE_URL + "
|
85
|
-
fetch_ec2_reserved_instance_pricing(EC2_BASE_URL + "
|
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.
|
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/
|
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
|
56
|
-
|
57
|
-
if
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
|
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:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
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-
|
18
|
+
date: 2012-10-21 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|