awscosts 0.0.8 → 0.0.9
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.
- checksums.yaml +4 -4
- data/README.md +2 -4
- data/awscosts.gemspec +1 -0
- data/fixtures/vcr_cassettes/AWSCosts_EBS.yml +17 -496
- data/fixtures/vcr_cassettes/AWSCosts_EC2OnDemand/EC2_type_of_linux.yml +63 -4583
- data/fixtures/vcr_cassettes/AWSCosts_EC2OnDemand/EC2_type_of_rhel.yml +63 -4585
- data/fixtures/vcr_cassettes/AWSCosts_EC2OnDemand/EC2_type_of_sles.yml +63 -4585
- data/fixtures/vcr_cassettes/AWSCosts_EC2OnDemand/EC2_type_of_windows.yml +63 -4583
- data/fixtures/vcr_cassettes/AWSCosts_EC2OnDemand/EC2_type_of_windows_with_sql.yml +63 -3535
- data/fixtures/vcr_cassettes/AWSCosts_EC2OnDemand/EC2_type_of_windows_with_sql_web.yml +63 -4060
- data/fixtures/vcr_cassettes/AWSCosts_EC2ReservedInstances/Reserved_instances/in_the_us-east-1_region/EC2_type_of_linux.yml +16 -5970
- data/fixtures/vcr_cassettes/AWSCosts_EC2ReservedInstances/Reserved_instances/in_the_us-east-1_region/EC2_type_of_rhel.yml +16 -5970
- data/fixtures/vcr_cassettes/AWSCosts_EC2ReservedInstances/Reserved_instances/in_the_us-east-1_region/EC2_type_of_sles.yml +16 -5970
- data/fixtures/vcr_cassettes/AWSCosts_EC2ReservedInstances/Reserved_instances/in_the_us-east-1_region/EC2_type_of_windows.yml +16 -5970
- data/fixtures/vcr_cassettes/AWSCosts_EC2ReservedInstances/Reserved_instances/in_the_us-east-1_region/EC2_type_of_windows_with_sql.yml +16 -5970
- data/fixtures/vcr_cassettes/AWSCosts_EC2ReservedInstances/Reserved_instances/in_the_us-east-1_region/EC2_type_of_windows_with_sql_web.yml +16 -5970
- data/fixtures/vcr_cassettes/AWSCosts_ELB.yml +17 -283
- data/fixtures/vcr_cassettes/AWSCosts_EMR.yml +12 -12
- data/fixtures/vcr_cassettes/AWSCosts_ElasticIPs.yml +17 -445
- data/fixtures/vcr_cassettes/AWSCosts_S3DataTransfer.yml +19 -925
- data/fixtures/vcr_cassettes/AWSCosts_S3Requests.yml +19 -454
- data/fixtures/vcr_cassettes/AWSCosts_S3Storage.yml +19 -1396
- data/lib/awscosts/cache.rb +26 -4
- data/lib/awscosts/ec2.rb +26 -5
- data/lib/awscosts/ec2_ebs.rb +3 -14
- data/lib/awscosts/ec2_ebs_optimized.rb +31 -0
- data/lib/awscosts/ec2_elastic_ips.rb +4 -4
- data/lib/awscosts/ec2_elb.rb +4 -4
- data/lib/awscosts/ec2_on_demand.rb +24 -19
- data/lib/awscosts/ec2_reserved_instances.rb +7 -8
- data/lib/awscosts/emr.rb +1 -2
- data/lib/awscosts/region.rb +12 -10
- data/lib/awscosts/s3.rb +4 -3
- data/lib/awscosts/s3_data_transfer.rb +7 -7
- data/lib/awscosts/s3_requests.rb +5 -6
- data/lib/awscosts/s3_storage.rb +7 -7
- data/lib/awscosts/version.rb +1 -1
- data/spec/awscosts/ec2_ebs_spec.rb +17 -33
- data/spec/awscosts/ec2_elastic_ips_spec.rb +2 -0
- data/spec/awscosts/ec2_reserved_instances_spec.rb +3 -0
- metadata +17 -2
data/lib/awscosts/cache.rb
CHANGED
@@ -1,15 +1,28 @@
|
|
1
1
|
require 'httparty'
|
2
|
-
require '
|
2
|
+
require 'oj'
|
3
3
|
|
4
4
|
module AWSCosts::Cache
|
5
5
|
extend self
|
6
6
|
|
7
7
|
BASE_URI = "http://aws.amazon.com"
|
8
|
+
BASE_JSONP_URI = "http://a0.awsstatic.com"
|
8
9
|
|
9
10
|
def get uri, base_uri = BASE_URI, &block
|
10
|
-
cache[uri] ||=
|
11
|
-
|
12
|
-
|
11
|
+
cache["#{base_uri}#{uri}"] ||= Oj::load(HTTParty.get("#{base_uri}#{uri}").body)
|
12
|
+
yield cache["#{base_uri}#{uri}"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_jsonp uri, base_uri = BASE_JSONP_URI, &block
|
16
|
+
attempts = 0
|
17
|
+
cache["#{base_uri}#{uri}"] ||= begin
|
18
|
+
extract_json_from_callback(HTTParty.get("#{base_uri}#{uri}").body)
|
19
|
+
rescue NoMethodError
|
20
|
+
attempts += 1
|
21
|
+
retry if attempts < 5
|
22
|
+
raise "Failed to retrieve or parse data for #{base_uri}#{uri}"
|
23
|
+
end
|
24
|
+
|
25
|
+
yield cache["#{base_uri}#{uri}"]
|
13
26
|
end
|
14
27
|
|
15
28
|
private
|
@@ -17,6 +30,15 @@ module AWSCosts::Cache
|
|
17
30
|
@cache ||= {}
|
18
31
|
end
|
19
32
|
|
33
|
+
def extract_json_from_callback body
|
34
|
+
body.match /^.*callback\((\{.*\})\);$/
|
35
|
+
body = $1
|
36
|
+
|
37
|
+
# Handle "json" with keys that are not quoted
|
38
|
+
# When we get {foo: "1"} instead of {"foo": "1"}
|
39
|
+
# http://stackoverflow.com/questions/2060356/parsing-json-without-quoted-keys
|
40
|
+
Oj::load(body.gsub(/(\w+)\s*:/, '"\1":'))
|
41
|
+
end
|
20
42
|
end
|
21
43
|
|
22
44
|
|
data/lib/awscosts/ec2.rb
CHANGED
@@ -2,6 +2,7 @@ require 'awscosts/ec2_on_demand'
|
|
2
2
|
require 'awscosts/ec2_reserved_instances'
|
3
3
|
require 'awscosts/ec2_elb'
|
4
4
|
require 'awscosts/ec2_ebs'
|
5
|
+
require 'awscosts/ec2_ebs_optimized'
|
5
6
|
require 'awscosts/ec2_elastic_ips'
|
6
7
|
|
7
8
|
class AWSCosts::EC2
|
@@ -11,28 +12,48 @@ class AWSCosts::EC2
|
|
11
12
|
TYPES = { windows: 'mswin', linux: 'linux', windows_with_sql: 'mswinSQL',
|
12
13
|
windows_with_sql_web: 'mswinSQLWeb', rhel: 'rhel', sles: 'sles' }
|
13
14
|
|
15
|
+
REGION_MAPPING = {
|
16
|
+
'us-east-1' => "us-east",
|
17
|
+
'us-west-1' => "us-west",
|
18
|
+
'us-west-2' => "us-west-2",
|
19
|
+
'eu-west-1' => "eu-ireland",
|
20
|
+
'eu-central-1' => "eu-central-1",
|
21
|
+
'ap-southeast-1' => "apac-sin",
|
22
|
+
'ap-southeast-2' =>"apac-syd",
|
23
|
+
'ap-northeast-1' =>"apac-tokyo",
|
24
|
+
'sa-east-1' => "sa-east-1"
|
25
|
+
}
|
26
|
+
|
14
27
|
def initialize region
|
15
28
|
@region = region
|
16
29
|
end
|
17
30
|
|
18
31
|
def on_demand(type)
|
32
|
+
raise ArgumentError.new("Unknown platform: #{type}") if TYPES[type].nil?
|
19
33
|
AWSCosts::EC2OnDemand.fetch(TYPES[type], self.region.name)
|
20
34
|
end
|
21
35
|
|
22
|
-
def reserved(type, utilisation= :light)
|
23
|
-
|
36
|
+
def reserved(type, utilisation = :light)
|
37
|
+
r = self.region.name
|
38
|
+
r = 'us-east' if r == 'us-east-1'
|
39
|
+
raise ArgumentError.new("Unknown platform: #{type}") if TYPES[type].nil?
|
40
|
+
AWSCosts::EC2ReservedInstances.fetch(TYPES[type], utilisation, r)
|
24
41
|
end
|
25
42
|
|
26
43
|
def elb
|
27
|
-
AWSCosts::ELB.fetch(self.region.
|
44
|
+
AWSCosts::ELB.fetch(REGION_MAPPING[self.region.name])
|
28
45
|
end
|
29
46
|
|
30
47
|
def ebs
|
31
|
-
AWSCosts::EBS.fetch(self.region.
|
48
|
+
AWSCosts::EBS.fetch(REGION_MAPPING[self.region.name])
|
49
|
+
end
|
50
|
+
|
51
|
+
def ebs_optimized
|
52
|
+
AWSCosts::EBSOptimized.fetch(REGION_MAPPING[self.region.name])
|
32
53
|
end
|
33
54
|
|
34
55
|
def elastic_ips
|
35
|
-
AWSCosts::ElasticIPs.fetch(self.region.
|
56
|
+
AWSCosts::ElasticIPs.fetch(REGION_MAPPING[self.region.name])
|
36
57
|
end
|
37
58
|
end
|
38
59
|
|
data/lib/awscosts/ec2_ebs.rb
CHANGED
@@ -1,11 +1,7 @@
|
|
1
1
|
require 'httparty'
|
2
|
-
require 'json'
|
3
2
|
|
4
3
|
class AWSCosts::EBS
|
5
4
|
|
6
|
-
TYPES = { 'ebsVols' => :standard, 'ebsPIOPSVols' => :provisioned_iops,
|
7
|
-
'ebsSnapsToS3' => :snapshots_to_s3 }
|
8
|
-
|
9
5
|
def initialize data
|
10
6
|
@data= data
|
11
7
|
end
|
@@ -15,17 +11,10 @@ class AWSCosts::EBS
|
|
15
11
|
end
|
16
12
|
|
17
13
|
def self.fetch region
|
18
|
-
transformed= AWSCosts::Cache.
|
14
|
+
transformed = AWSCosts::Cache.get_jsonp('/pricing/1/ebs/pricing-ebs.min.js') do |data|
|
19
15
|
result = {}
|
20
|
-
data['config']['regions'].each do |
|
21
|
-
|
22
|
-
region['types'].each do |type|
|
23
|
-
container[TYPES[type['name']]] = {}
|
24
|
-
type['values'].each do |value|
|
25
|
-
container[TYPES[type['name']]][value['rate']] = value['prices']['USD'].to_f
|
26
|
-
end
|
27
|
-
end
|
28
|
-
result[region['region']] = container
|
16
|
+
data['config']['regions'].each do |r|
|
17
|
+
result[r['region']] = r['types']
|
29
18
|
end
|
30
19
|
result
|
31
20
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
class AWSCosts::EBSOptimized
|
4
|
+
|
5
|
+
def initialize data
|
6
|
+
@data = data
|
7
|
+
end
|
8
|
+
|
9
|
+
def price type = nil
|
10
|
+
type.nil? ? @data : @data[type]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.fetch region
|
14
|
+
transformed = AWSCosts::Cache.get_jsonp('/pricing/1/ec2/pricing-ebs-optimized-instances.min.js') do |data|
|
15
|
+
result = {}
|
16
|
+
data['config']['regions'].each do |r|
|
17
|
+
container = {}
|
18
|
+
r['instanceTypes'].each do |type|
|
19
|
+
type['sizes'].each do |size|
|
20
|
+
container[size['size']] = size['valueColumns'].select{|v| v['name'] == 'ebsOptimized'}.first['prices']['USD'].to_f
|
21
|
+
end
|
22
|
+
end
|
23
|
+
result[r['region']] = container
|
24
|
+
end
|
25
|
+
result
|
26
|
+
end
|
27
|
+
self.new(transformed[region])
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
@@ -25,16 +25,16 @@ class AWSCosts::ElasticIPs
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def self.fetch region
|
28
|
-
transformed= AWSCosts::Cache.
|
28
|
+
transformed = AWSCosts::Cache.get_jsonp('/pricing/1/ec2/pricing-elastic-ips.min.js') do |data|
|
29
29
|
result = {}
|
30
|
-
data['config']['regions'].each do |
|
30
|
+
data['config']['regions'].each do |r|
|
31
31
|
container = {}
|
32
|
-
|
32
|
+
r['types'].each do |type|
|
33
33
|
type['values'].each do |value|
|
34
34
|
container[value['rate']] = value['prices']['USD'].to_f
|
35
35
|
end
|
36
36
|
end
|
37
|
-
result[
|
37
|
+
result[r['region']] = container
|
38
38
|
end
|
39
39
|
result
|
40
40
|
end
|
data/lib/awscosts/ec2_elb.rb
CHANGED
@@ -13,16 +13,16 @@ class AWSCosts::ELB
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.fetch region
|
16
|
-
transformed= AWSCosts::Cache.
|
16
|
+
transformed = AWSCosts::Cache.get_jsonp('/pricing/1/ec2/pricing-elb.min.js') do |data|
|
17
17
|
result = {}
|
18
|
-
data['config']['regions'].each do |
|
18
|
+
data['config']['regions'].each do |r|
|
19
19
|
container = {}
|
20
|
-
|
20
|
+
r['types'].each do |type|
|
21
21
|
type['values'].each do |value|
|
22
22
|
container[value['rate']] = value['prices']['USD'].to_f
|
23
23
|
end
|
24
24
|
end
|
25
|
-
result[
|
25
|
+
result[r['region']] = container
|
26
26
|
end
|
27
27
|
result
|
28
28
|
end
|
@@ -22,7 +22,7 @@ class AWSCosts::EC2OnDemand
|
|
22
22
|
'hiIoODI.xxxxl' => 'hi1.4xlarge' }
|
23
23
|
|
24
24
|
def initialize data
|
25
|
-
@data= data
|
25
|
+
@data = data
|
26
26
|
end
|
27
27
|
|
28
28
|
def price size=nil
|
@@ -30,30 +30,35 @@ class AWSCosts::EC2OnDemand
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def self.fetch type, region
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
platform_cost
|
43
|
-
|
33
|
+
result = {}
|
34
|
+
['/pricing/1/ec2/%s-od.min.js', '/pricing/1/ec2/previous-generation/%s-od.min.js'].each do |uri|
|
35
|
+
AWSCosts::Cache.get_jsonp(uri % type) do |data|
|
36
|
+
data['config']['regions'].each do |r|
|
37
|
+
result[r['region']] ||= {}
|
38
|
+
platforms = result[r['region']]
|
39
|
+
r['instanceTypes'].each do |instance_type|
|
40
|
+
instance_type['sizes'].each do |instance_size|
|
41
|
+
size = instance_size['size']
|
42
|
+
platform_cost = Hash.new({})
|
43
|
+
instance_size['valueColumns'].each do |value|
|
44
|
+
# Don't return 0.0 for "N/A" since that is misleading
|
45
|
+
platform_cost[value['name']] = value['prices']['USD'] == 'N/A' ? nil : value['prices']['USD'].to_f
|
46
|
+
end
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
platform_cost.each_pair do |p,v|
|
49
|
+
platforms[p] = {} unless platforms.key?(p)
|
50
|
+
platforms[p][size] = v
|
51
|
+
end
|
48
52
|
end
|
49
53
|
end
|
50
54
|
end
|
51
|
-
result[region['region']] = platforms
|
52
55
|
end
|
53
|
-
result
|
54
56
|
end
|
55
|
-
|
56
|
-
|
57
|
+
|
58
|
+
raise "No result for region #{region} while fetching EC2 OnDemand Pricing" if result[region].nil?
|
59
|
+
raise "No result for #{type} in region #{region} while fetching EC2 OnDemand Pricing" if result[region][type].nil?
|
60
|
+
|
61
|
+
self.new(result[region][type])
|
57
62
|
end
|
58
63
|
|
59
64
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'httparty'
|
2
|
-
require 'json'
|
3
2
|
class AWSCosts::EC2ReservedInstances
|
4
3
|
|
5
4
|
TERMS = { one_year: 'yrTerm1', three_year: 'yrTerm3' }
|
@@ -42,19 +41,19 @@ class AWSCosts::EC2ReservedInstances
|
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
45
|
-
|
46
44
|
def self.fetch type, utilisation, region
|
47
|
-
transformed= AWSCosts::Cache.
|
45
|
+
transformed = AWSCosts::Cache.get_jsonp("/pricing/1/ec2/#{type}-ri-#{utilisation}.min.js") do |data|
|
48
46
|
result = {}
|
49
|
-
data['config']['regions'].each do |
|
47
|
+
data['config']['regions'].each do |r|
|
50
48
|
platforms = {}
|
51
|
-
|
49
|
+
r['instanceTypes'].each do |instance_type|
|
52
50
|
instance_type['sizes'].each do |instance_size|
|
53
51
|
size = instance_size['size']
|
54
52
|
platform_cost = Hash.new({})
|
55
53
|
|
56
54
|
instance_size['valueColumns'].each do |value|
|
57
|
-
|
55
|
+
# Don't return 0.0 for "N/A" since that is misleading
|
56
|
+
platform_cost[value['name']] = value['prices']['USD'] == 'N/A' ? nil : value['prices']['USD'].to_f
|
58
57
|
end
|
59
58
|
|
60
59
|
platform_cost.each_pair do |p,v|
|
@@ -63,11 +62,11 @@ class AWSCosts::EC2ReservedInstances
|
|
63
62
|
end
|
64
63
|
end
|
65
64
|
end
|
66
|
-
result[
|
65
|
+
result[r['region']] = platforms
|
67
66
|
end
|
68
67
|
result
|
69
68
|
end
|
70
|
-
|
69
|
+
self.new(transformed[region])
|
71
70
|
end
|
72
71
|
|
73
72
|
end
|
data/lib/awscosts/emr.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'httparty'
|
2
|
-
require 'json'
|
3
2
|
|
4
3
|
class AWSCosts::EMR
|
5
4
|
|
@@ -45,7 +44,7 @@ class AWSCosts::EMR
|
|
45
44
|
end
|
46
45
|
platform_cost.each_pair do |p,v|
|
47
46
|
platforms[p] = {} unless platforms.key?(p)
|
48
|
-
platforms[p][
|
47
|
+
platforms[p][size] = v
|
49
48
|
end
|
50
49
|
end
|
51
50
|
end
|
data/lib/awscosts/region.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
|
2
2
|
class AWSCosts::Region
|
3
3
|
|
4
|
-
attr_reader :name, :full_name, :price_mapping
|
4
|
+
attr_reader :name, :full_name, :price_mapping, :emr_mapping
|
5
5
|
|
6
6
|
SUPPORTED = {
|
7
|
-
'us-east-1' => { :full_name => 'US (Northern Virginia)', :price_mapping => 'us-east' },
|
8
|
-
'us-west-1' => { :full_name => 'US (Northern California)', :price_mapping => 'us-west' },
|
9
|
-
'us-west-2' => { :full_name => 'US (Oregon)', :price_mapping => 'us-west-2' },
|
10
|
-
'eu-west-1' => { :full_name => 'EU (Ireland)', :price_mapping => 'eu-ireland' },
|
11
|
-
'
|
12
|
-
'ap-southeast-
|
13
|
-
'ap-
|
14
|
-
'
|
7
|
+
'us-east-1' => { :full_name => 'US (Northern Virginia)', :price_mapping => 'us-east-1', :emr_mapping => 'us-east' },
|
8
|
+
'us-west-1' => { :full_name => 'US (Northern California)', :price_mapping => 'us-west-1', :emr_mapping => 'us-west' },
|
9
|
+
'us-west-2' => { :full_name => 'US (Oregon)', :price_mapping => 'us-west-2', :emr_mapping => 'us-west-2' },
|
10
|
+
'eu-west-1' => { :full_name => 'EU (Ireland)', :price_mapping => 'eu-west-1', :emr_mapping => 'eu-ireland' },
|
11
|
+
'eu-central-1' => { :full_name => 'EU (Frankfurt)' },
|
12
|
+
'ap-southeast-1' => { :full_name => 'Asia Pacific (Singapore)', :price_mapping => 'ap-southeast-1', :emr_mapping => 'apac-sin' },
|
13
|
+
'ap-southeast-2' => { :full_name => 'Asia Pacific (Sydney)', :price_mapping => 'ap-southeast-2', :emr_mapping => 'apac-syd' },
|
14
|
+
'ap-northeast-1' => { :full_name => 'Asia Pacific (Tokyo)', :price_mapping => 'ap-northeast-1', :emr_mapping => 'apac-tokyo' },
|
15
|
+
'sa-east-1' => { :full_name => 'South America (Sao Paulo)', :price_mapping => 'sa-east-1', :emr_mapping => 'sa-east-1' }
|
15
16
|
}
|
16
17
|
|
17
18
|
def self.find name
|
@@ -24,7 +25,7 @@ class AWSCosts::Region
|
|
24
25
|
end
|
25
26
|
|
26
27
|
def emr
|
27
|
-
AWSCosts::EMR.fetch(self.
|
28
|
+
AWSCosts::EMR.fetch(self.emr_mapping)
|
28
29
|
end
|
29
30
|
|
30
31
|
def s3
|
@@ -36,6 +37,7 @@ class AWSCosts::Region
|
|
36
37
|
@name = name
|
37
38
|
@full_name = SUPPORTED[name][:full_name]
|
38
39
|
@price_mapping = SUPPORTED[name][:price_mapping]
|
40
|
+
@emr_mapping = SUPPORTED[name][:emr_mapping]
|
39
41
|
end
|
40
42
|
|
41
43
|
end
|
data/lib/awscosts/s3.rb
CHANGED
@@ -11,6 +11,7 @@ class AWSCosts::S3
|
|
11
11
|
'us-west-1' => "us-west-1",
|
12
12
|
'us-west-2' => "us-west-2",
|
13
13
|
'eu-west-1' => "eu-west-1",
|
14
|
+
'eu-central-1' => "eu-central-1",
|
14
15
|
'ap-southeast-1' => "ap-southeast-1",
|
15
16
|
'ap-southeast-2' =>"ap-southeast-2",
|
16
17
|
'ap-northeast-1' =>"ap-northeast-1",
|
@@ -22,15 +23,15 @@ class AWSCosts::S3
|
|
22
23
|
end
|
23
24
|
|
24
25
|
def storage
|
25
|
-
AWSCosts::S3Storage.fetch(
|
26
|
+
AWSCosts::S3Storage.fetch(@region)
|
26
27
|
end
|
27
28
|
|
28
29
|
def data_transfer
|
29
|
-
AWSCosts::S3DataTransfer.fetch(
|
30
|
+
AWSCosts::S3DataTransfer.fetch(@region)
|
30
31
|
end
|
31
32
|
|
32
33
|
def requests
|
33
|
-
AWSCosts::S3Requests.fetch(
|
34
|
+
AWSCosts::S3Requests.fetch(@region)
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'httparty'
|
2
|
-
require 'json'
|
3
2
|
|
4
3
|
class AWSCosts::S3DataTransfer
|
5
4
|
|
6
5
|
TYPES = %w{dataXferInS3, dataXferOutS3CrossRegion, dataXferOutS3}
|
7
6
|
|
8
7
|
def initialize data
|
9
|
-
@data= data
|
8
|
+
@data = data
|
10
9
|
end
|
11
10
|
|
12
11
|
def price type = nil
|
@@ -14,17 +13,18 @@ class AWSCosts::S3DataTransfer
|
|
14
13
|
end
|
15
14
|
|
16
15
|
def self.fetch region
|
17
|
-
transformed= AWSCosts::Cache.
|
16
|
+
transformed = AWSCosts::Cache.get_jsonp("/pricing/1/s3/pricing-data-transfer-s3.min.js") do |data|
|
18
17
|
result = {}
|
19
|
-
data['config']['regions'].each do |
|
18
|
+
data['config']['regions'].each do |r|
|
20
19
|
types = {}
|
21
|
-
|
20
|
+
r['types'].each do |type|
|
22
21
|
types[type['name']] = {}
|
23
22
|
type['tiers'].each do |tier|
|
24
|
-
|
23
|
+
# Don't return 0.0 for "contactus" since that is misleading
|
24
|
+
types[type['name']][tier['name']] = tier['prices']['USD'] == 'contactus' ? nil : tier['prices']['USD'].to_f
|
25
25
|
end
|
26
26
|
end
|
27
|
-
result[
|
27
|
+
result[r['region']] = types
|
28
28
|
end
|
29
29
|
result
|
30
30
|
end
|