amazon-pricing 0.1.63 → 0.1.64

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- amazon-pricing (0.1.63)
4
+ amazon-pricing (0.1.64)
5
5
  mechanize (~> 2.7.2)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -73,7 +73,7 @@ Additional Resources
73
73
  Credits
74
74
  -------
75
75
 
76
- Thanks for Amazon developers for provided Json APIs to the pricing data (albeit undocumented).
76
+ Thanks for Amazon developers for provided JSON APIs to the pricing data (albeit undocumented).
77
77
 
78
78
  Contact
79
79
  -------
@@ -4,7 +4,10 @@ require 'mechanize'
4
4
 
5
5
  Dir[File.join(File.dirname(__FILE__), 'amazon-pricing/definitions/*.rb')].sort.each { |lib| require lib }
6
6
 
7
+ require 'amazon-pricing/common/ec2_common'
8
+
7
9
  require 'amazon-pricing/aws-price-list'
8
10
  require 'amazon-pricing/ec2-price-list'
11
+ require 'amazon-pricing/ec2-di-price-list'
9
12
  require 'amazon-pricing/rds-price-list'
10
13
  require 'amazon-pricing/dynamo-db-price-list'
@@ -101,6 +101,10 @@ module AwsPricing
101
101
  EBS_BASE_URL = "http://a0.awsstatic.com/pricing/1/ebs/"
102
102
  RDS_BASE_URL = "http://a0.awsstatic.com/pricing/1/rds/"
103
103
 
104
+ DI_OD_BASE_URL = "http://a0.awsstatic.com/pricing/1/dedicated-instances/"
105
+ RESERVED_DI_BASE_URL = "http://a0.awsstatic.com/pricing/1/ec2/ri-v2/"
106
+ RESERVED_DI_PREV_GEN_BASE_URL = "http://a0.awsstatic.com/pricing/1/ec2/previous-generation/ri-v2/"
107
+
104
108
  def convert_region(name)
105
109
  case name
106
110
  when "us-east"
@@ -0,0 +1,77 @@
1
+ module AwsPricing
2
+ module Ec2Common
3
+ # Retrieves the EC2 on-demand instance pricing.
4
+ # type_of_instance = :ondemand, :light, :medium, :heavy
5
+ def fetch_ec2_instance_pricing(url, type_of_instance, operating_system)
6
+ res = PriceList.fetch_url(url)
7
+ res['config']['regions'].each do |reg|
8
+ region_name = reg['region']
9
+ region = get_region(region_name)
10
+ if region.nil?
11
+ $stderr.puts "[fetch_ec2_instance_pricing] WARNING: unable to find region #{region_name}"
12
+ next
13
+ end
14
+ # e.g. type = {"type"=>"hiCPUODI", "sizes"=>[{"size"=>"med", "valueColumns"=>[{"name"=>"mswinSQL", "prices"=>{"USD"=>"N/A"}}]}, {"size"=>"xl", "valueColumns"=>[{"name"=>"mswinSQL", "prices"=>{"USD"=>"2.427"}}]}]}
15
+ reg['instanceTypes'].each do |type|
16
+ # e.g. size = {"size"=>"xl", "valueColumns"=>[{"name"=>"mswinSQL", "prices"=>{"USD"=>"2.427"}}]}
17
+ # Amazon now can return array or hash here (hash = only 1 item)
18
+ items = type['sizes']
19
+ items = [type] if items.nil?
20
+ items.each do |size|
21
+ begin
22
+ api_name, name = Ec2InstanceType.get_name(type["type"], size["size"], type_of_instance != :ondemand)
23
+ instance_type = region.add_or_update_ec2_instance_type(api_name, name)
24
+ instance_type.update_pricing(operating_system, type_of_instance, size)
25
+ rescue UnknownTypeError
26
+ $stderr.puts "[fetch_ec2_instance_pricing] WARNING: encountered #{$!.message}"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ # With v2 of RIs they have an entirely new format that needs to be parsed
34
+ def fetch_ec2_instance_pricing_ri_v2(url, operating_system)
35
+ res = PriceList.fetch_url(url)
36
+ res['config']['regions'].each do |reg|
37
+ region_name = reg['region']
38
+ region = get_region(region_name)
39
+ if region.nil?
40
+ $stderr.puts "[fetch_ec2_instance_pricing_ri_v2] WARNING: unable to find region #{region_name}"
41
+ next
42
+ end
43
+ reg['instanceTypes'].each do |type|
44
+ api_name = type["type"]
45
+ instance_type = region.get_instance_type(api_name)
46
+ if instance_type.nil?
47
+ $stderr.puts "[fetch_ec2_instance_pricing_ri_v2] WARNING: new reserved instances not found for #{api_name} in #{region_name}"
48
+ next
49
+ end
50
+
51
+ type["terms"].each do |term|
52
+ term["purchaseOptions"].each do |option|
53
+ case option["purchaseOption"]
54
+ when "noUpfront"
55
+ reservation_type = :noupfront
56
+ when "allUpfront"
57
+ reservation_type = :allupfront
58
+ when "partialUpfront"
59
+ reservation_type = :partialupfront
60
+ end
61
+
62
+ duration = term["term"]
63
+ prices = option["valueColumns"]
64
+ upfront = prices.select{|i| i["name"] == "upfront"}.first
65
+ price = upfront["prices"]["USD"]
66
+ instance_type.update_pricing_new(operating_system, reservation_type, price.to_f, duration, true) unless reservation_type == :noupfront || price == "N/A"
67
+ hourly = prices.select{|i| i["name"] == "monthlyStar"}.first
68
+ price = hourly["prices"]["USD"]
69
+ instance_type.update_pricing_new(operating_system, reservation_type, price.to_f * 12 / 365 / 24, duration, false) unless reservation_type == :allupfront || price == "N/A"
70
+ end
71
+ end
72
+
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,48 @@
1
+ module AwsPricing
2
+ class Ec2DiPriceList < PriceList
3
+ include AwsPricing::Ec2Common
4
+
5
+ def initialize
6
+ super
7
+ InstanceType.populate_lookups
8
+ get_ec2_di_od_pricing
9
+ get_ec2_reserved_di_pricing
10
+ end
11
+
12
+ protected
13
+
14
+ @@OS_TYPES = [
15
+ ['linux', 'linux-unix'],
16
+ ['rhel', 'red-hat-enterprise-linux'],
17
+ ['sles', 'suse-linux'],
18
+ ['mswin', 'windows'],
19
+ ['mswinSQL', 'windows-with-sql-server-standard'],
20
+ ['mswinSQLWeb', 'windows-with-sql-server-web'],
21
+ ['mswinSQLEnterprise', 'windows-with-sql-server-enterprise']
22
+ ]
23
+
24
+ OS_INDEX = 0
25
+ OD_OS_INDEX = 0
26
+ RI_OS_INDEX = 1
27
+
28
+ def get_ec2_di_od_pricing
29
+ for_each_os_and_name(OS_INDEX, OD_OS_INDEX) do |os, os_name|
30
+ fetch_ec2_instance_pricing(DI_OD_BASE_URL + "di-#{os_name}-od.min.js", :ondemand, os.to_sym)
31
+ end
32
+ end
33
+
34
+ def get_ec2_reserved_di_pricing
35
+ for_each_os_and_name(OS_INDEX, RI_OS_INDEX) do |os, os_name|
36
+ fetch_ec2_instance_pricing_ri_v2(RESERVED_DI_BASE_URL + "#{os_name}-dedicated.min.js", os.to_sym)
37
+ next if os == 'mswinSQLEnterprise' # No SQL Enterprise for previous generation
38
+ fetch_ec2_instance_pricing_ri_v2(RESERVED_DI_PREV_GEN_BASE_URL + "#{os_name}-dedicated.min.js", os.to_sym)
39
+ end
40
+ end
41
+
42
+ def for_each_os_and_name os_index, os_name_index
43
+ @@OS_TYPES.inject({}) {|h,o| h[o[os_index]]=o[os_name_index];h}.each do |os, os_name|
44
+ yield os, os_name
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,6 +1,7 @@
1
1
  module AwsPricing
2
2
  class Ec2PriceList < PriceList
3
-
3
+ include AwsPricing::Ec2Common
4
+
4
5
  def initialize
5
6
  super
6
7
  InstanceType.populate_lookups
@@ -56,81 +57,6 @@ module AwsPricing
56
57
  end
57
58
  end
58
59
 
59
- # Retrieves the EC2 on-demand instance pricing.
60
- # type_of_instance = :ondemand, :light, :medium, :heavy
61
- def fetch_ec2_instance_pricing(url, type_of_instance, operating_system)
62
- res = PriceList.fetch_url(url)
63
- res['config']['regions'].each do |reg|
64
- region_name = reg['region']
65
- region = get_region(region_name)
66
- if region.nil?
67
- $stderr.puts "[fetch_ec2_instance_pricing] WARNING: unable to find region #{region_name}"
68
- next
69
- end
70
- # e.g. type = {"type"=>"hiCPUODI", "sizes"=>[{"size"=>"med", "valueColumns"=>[{"name"=>"mswinSQL", "prices"=>{"USD"=>"N/A"}}]}, {"size"=>"xl", "valueColumns"=>[{"name"=>"mswinSQL", "prices"=>{"USD"=>"2.427"}}]}]}
71
- reg['instanceTypes'].each do |type|
72
- # e.g. size = {"size"=>"xl", "valueColumns"=>[{"name"=>"mswinSQL", "prices"=>{"USD"=>"2.427"}}]}
73
- # Amazon now can return array or hash here (hash = only 1 item)
74
- items = type['sizes']
75
- items = [type] if items.nil?
76
- items.each do |size|
77
- begin
78
- api_name, name = Ec2InstanceType.get_name(type["type"], size["size"], type_of_instance != :ondemand)
79
- instance_type = region.add_or_update_ec2_instance_type(api_name, name)
80
- instance_type.update_pricing(operating_system, type_of_instance, size)
81
- rescue UnknownTypeError
82
- $stderr.puts "[fetch_ec2_instance_pricing] WARNING: encountered #{$!.message}"
83
- end
84
- end
85
- end
86
- end
87
- end
88
-
89
- # With v2 of RIs they have an entirely new format that needs to be parsed
90
- def fetch_ec2_instance_pricing_ri_v2(url, operating_system)
91
- res = PriceList.fetch_url(url)
92
- res['config']['regions'].each do |reg|
93
- region_name = reg['region']
94
- region = get_region(region_name)
95
- if region.nil?
96
- $stderr.puts "[fetch_ec2_instance_pricing_ri_v2] WARNING: unable to find region #{region_name}"
97
- next
98
- end
99
- reg['instanceTypes'].each do |type|
100
- api_name = type["type"]
101
- instance_type = region.get_instance_type(api_name)
102
- if instance_type.nil?
103
- $stderr.puts "[fetch_ec2_instance_pricing_ri_v2] WARNING: new reserved instances not found for #{api_name} in #{region_name}"
104
- next
105
- end
106
-
107
- type["terms"].each do |term|
108
- term["purchaseOptions"].each do |option|
109
- case option["purchaseOption"]
110
- when "noUpfront"
111
- reservation_type = :noupfront
112
- when "allUpfront"
113
- reservation_type = :allupfront
114
- when "partialUpfront"
115
- reservation_type = :partialupfront
116
- end
117
-
118
- duration = term["term"]
119
- prices = option["valueColumns"]
120
- upfront = prices.select{|i| i["name"] == "upfront"}.first
121
- price = upfront["prices"]["USD"]
122
- instance_type.update_pricing_new(operating_system, reservation_type, price.to_f, duration, true) unless reservation_type == :noupfront || price == "N/A"
123
- hourly = prices.select{|i| i["name"] == "monthlyStar"}.first
124
- price = hourly["prices"]["USD"]
125
- instance_type.update_pricing_new(operating_system, reservation_type, price.to_f * 12 / 365 / 24, duration, false) unless reservation_type == :allupfront || price == "N/A"
126
- end
127
- end
128
-
129
- end
130
- end
131
- end
132
-
133
-
134
60
  def fetch_ec2_ebs_pricing
135
61
  res = PriceList.fetch_url(EBS_BASE_URL + "pricing-ebs.min.js")
136
62
  res["config"]["regions"].each do |ebs_types|
@@ -8,5 +8,5 @@
8
8
  # Home:: http://github.com/CloudHealth/amazon-pricing
9
9
  #++
10
10
  module AwsPricing
11
- VERSION = '0.1.63'
11
+ VERSION = '0.1.64'
12
12
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amazon-pricing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.63
4
+ version: 0.1.64
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-06-29 00:00:00.000000000 Z
12
+ date: 2015-08-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mechanize
@@ -51,6 +51,7 @@ files:
51
51
  - lib/.DS_Store
52
52
  - lib/amazon-pricing.rb
53
53
  - lib/amazon-pricing/aws-price-list.rb
54
+ - lib/amazon-pricing/common/ec2_common.rb
54
55
  - lib/amazon-pricing/definitions/category-type.rb
55
56
  - lib/amazon-pricing/definitions/database-type.rb
56
57
  - lib/amazon-pricing/definitions/ebs-price.rb
@@ -60,6 +61,7 @@ files:
60
61
  - lib/amazon-pricing/definitions/rds-instance-type.rb
61
62
  - lib/amazon-pricing/definitions/region.rb
62
63
  - lib/amazon-pricing/dynamo-db-price-list.rb
64
+ - lib/amazon-pricing/ec2-di-price-list.rb
63
65
  - lib/amazon-pricing/ec2-price-list.rb
64
66
  - lib/amazon-pricing/helpers/instance-type.rb
65
67
  - lib/amazon-pricing/rds-price-list.rb