awscosts 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +86 -0
- data/Rakefile +11 -0
- data/awscosts.gemspec +26 -0
- data/lib/awscosts/ec2.rb +29 -0
- data/lib/awscosts/ec2_elb.rb +36 -0
- data/lib/awscosts/ec2_on_demand.rb +67 -0
- data/lib/awscosts/ec2_reserved_instances.rb +81 -0
- data/lib/awscosts/region.rb +34 -0
- data/lib/awscosts/version.rb +3 -0
- data/lib/awscosts.rb +13 -0
- data/spec/awscosts/ec2_spec.rb +12 -0
- data/spec/awscosts/region_spec.rb +32 -0
- data/spec/spec_helper.rb +5 -0
- metadata +136 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Stephen Bartlett
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# Awscosts
|
2
|
+
|
3
|
+
AWSCosts allows programmatic access to AWS pricing.
|
4
|
+
|
5
|
+
Useful for calculating the running costs of your fleet of EC2 instances and
|
6
|
+
associated services such as ELBs, RDS, CloudWatch, etc.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
gem 'awscosts'
|
13
|
+
|
14
|
+
Or install it yourself as:
|
15
|
+
|
16
|
+
$ gem install awscosts
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
Pricing is usually defined by region
|
21
|
+
|
22
|
+
region = AWSCosts.region 'us-east-1'
|
23
|
+
|
24
|
+
### On Demand
|
25
|
+
|
26
|
+
To find the price of all on-demand EC2 instances running linux
|
27
|
+
|
28
|
+
region.ec2.on_demand(:linux).price
|
29
|
+
|
30
|
+
You can pass an argument to price to filter by the instance type.
|
31
|
+
|
32
|
+
region.ec2.on_demand(:linux).price('m1.medium')
|
33
|
+
|
34
|
+
### Reserved
|
35
|
+
|
36
|
+
To find the **upfront** price of reserving Windows instance for light utilization
|
37
|
+
|
38
|
+
region.ec2.reserved(:windows, :light).upfront
|
39
|
+
|
40
|
+
To find the **hourly** price of a `m1.large` reserved Windows with SQL instance for medium utilization
|
41
|
+
|
42
|
+
region.ec2.reserved(:windows_with_sql, :medium).hourly('m1.large')
|
43
|
+
|
44
|
+
### ELB
|
45
|
+
|
46
|
+
To find the hourly price of an ELB in the Sydney region.
|
47
|
+
|
48
|
+
AWSCosts.region('ap-southeast-2').ec2.elb.price_per_hour
|
49
|
+
|
50
|
+
To find the price per GB processed of an ELB in the Sydney region.
|
51
|
+
|
52
|
+
AWSCosts.region('ap-southeast-2').ec2.elb.price_per_gb
|
53
|
+
|
54
|
+
## Supported Services
|
55
|
+
|
56
|
+
The following AWS services are currently support (more to come):
|
57
|
+
|
58
|
+
* On-demand instances
|
59
|
+
* Reserved light utilisation
|
60
|
+
* Reserved medium utilisation
|
61
|
+
* Reserved heavy utilisation
|
62
|
+
* Elastic Load Balancer (ELB)
|
63
|
+
|
64
|
+
EC2 platforms:
|
65
|
+
|
66
|
+
* Linux (:linux)
|
67
|
+
* RHEL (:rhel)
|
68
|
+
* SLES (:sles)
|
69
|
+
* Windows (:windows)
|
70
|
+
* Windows with SQL (:windows_with_sql)
|
71
|
+
* Windows with SQL Web (:windows_with_sql_web)
|
72
|
+
|
73
|
+
## Roadmap
|
74
|
+
|
75
|
+
Possible items on the roadmap are:
|
76
|
+
|
77
|
+
1. Cost calculation using a DSL to describe your AWS environment.
|
78
|
+
2. Cost calculation from a Cloudformation template.
|
79
|
+
|
80
|
+
## Contributing
|
81
|
+
|
82
|
+
1. Fork it
|
83
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
84
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
85
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
86
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
|
4
|
+
desc "Run the tests"
|
5
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
6
|
+
t.pattern = ENV['rspec_pattern'] || "spec/**/*_spec.rb"
|
7
|
+
t.rspec_opts = [
|
8
|
+
"--colour",
|
9
|
+
"--require", "spec_helper"
|
10
|
+
]
|
11
|
+
end
|
data/awscosts.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'awscosts/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "awscosts"
|
8
|
+
spec.version = AWSCosts::VERSION
|
9
|
+
spec.authors = ["Stephen Bartlett"]
|
10
|
+
spec.email = ["stephenb@rtlett.org"]
|
11
|
+
spec.description = %q{AWSCosts provides an easier way to calculate the costs of running your project in AWS}
|
12
|
+
spec.summary = %q{Programmatic access to AWS pricing}
|
13
|
+
spec.homepage = "https://github.com/srbartlett/awscosts"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "httparty", "~> 0.11.0"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency 'rspec'
|
26
|
+
end
|
data/lib/awscosts/ec2.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'awscosts/ec2_on_demand'
|
2
|
+
require 'awscosts/ec2_reserved_instances'
|
3
|
+
require 'awscosts/ec2_elb'
|
4
|
+
|
5
|
+
class AWSCosts::EC2
|
6
|
+
|
7
|
+
attr_reader :region
|
8
|
+
|
9
|
+
TYPES = { windows: 'mswin', linux: 'linux', windows_with_sql: 'mswinSQL',
|
10
|
+
windows_with_sql_web: 'mswinSQLWeb', rhel: 'rhel', sles: 'sles' }
|
11
|
+
|
12
|
+
def initialize region
|
13
|
+
@region = region
|
14
|
+
end
|
15
|
+
|
16
|
+
def on_demand(type)
|
17
|
+
AWSCosts::EC2OnDemand.fetch(type, self.region.price_mapping)
|
18
|
+
end
|
19
|
+
|
20
|
+
def reserved(type, utilisation= :light)
|
21
|
+
AWSCosts::EC2ReservedInstances.fetch(type, utilisation, self.region.price_mapping)
|
22
|
+
end
|
23
|
+
|
24
|
+
def elb
|
25
|
+
AWSCosts::ELB.fetch(self.region.price_mapping)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class AWSCosts::ELB
|
5
|
+
|
6
|
+
def initialize data
|
7
|
+
@data= data
|
8
|
+
end
|
9
|
+
|
10
|
+
def price_per_hour
|
11
|
+
@data['perELBHour']
|
12
|
+
end
|
13
|
+
|
14
|
+
def price_per_gb
|
15
|
+
@data['perGBProcessed']
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.fetch region
|
19
|
+
@fetch ||= begin
|
20
|
+
result = {}
|
21
|
+
data= JSON.parse(HTTParty.get('http://aws.amazon.com/ec2/pricing/pricing-elb.json').body)
|
22
|
+
data['config']['regions'].each do |region|
|
23
|
+
container = {}
|
24
|
+
region['types'].each do |type|
|
25
|
+
type['values'].each do |value|
|
26
|
+
container[value['rate']] = value['prices']['USD'].to_f
|
27
|
+
end
|
28
|
+
end
|
29
|
+
result[region['region']] = container
|
30
|
+
end
|
31
|
+
result
|
32
|
+
end
|
33
|
+
self.new(@fetch[region])
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
class AWSCosts::EC2OnDemand
|
5
|
+
|
6
|
+
TYPE_TRANSLATION = { 'stdODI.sm' => 'm1.small',
|
7
|
+
'stdODI.med' => 'm1.medium',
|
8
|
+
'stdODI.lg' => 'm1.large',
|
9
|
+
'stdODI.xl' => 'm1.xlarge',
|
10
|
+
'secgenstdODI.xl' => 'm3.xlarge',
|
11
|
+
'secgenstdODI.xxl' => 'm3.2xlarge',
|
12
|
+
'uODI.u' => 't1.micro',
|
13
|
+
'hiMemODI.xl' => 'm2.xlarge',
|
14
|
+
'hiMemODI.xxl' => 'm2.2xlarge',
|
15
|
+
'hiMemODI.xxxxl' => 'm2.4xlarge',
|
16
|
+
'hiCPUODI.med' => 'c1.medium',
|
17
|
+
'hiCPUODI.xl' => 'c1.xlarge',
|
18
|
+
'clusterComputeI.xxxxl' => 'cc1.4xlarge',
|
19
|
+
'clusterComputeI.xxxxxxxxl' => 'cc2.8xlarge',
|
20
|
+
'clusterGPUI.xxxxl' => 'cg1.4xlarge',
|
21
|
+
'clusterHiMemODI.xxxxxxxxl' => 'cr1.8xlarge',
|
22
|
+
'hiStoreODI.xxxxxxxxl' => 'hs1.8xlarge',
|
23
|
+
'hiIoODI.xxxxl' => 'hi1.4xlarge' }
|
24
|
+
|
25
|
+
def initialize type, data
|
26
|
+
@type = type
|
27
|
+
@data= data
|
28
|
+
end
|
29
|
+
|
30
|
+
def price size=nil
|
31
|
+
size ? @data[TYPE_MAPPING[@type]][size] : @data[TYPE_MAPPING[@type]]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.fetch type, region
|
35
|
+
raw_data= cache[type] ||= begin
|
36
|
+
result = {}
|
37
|
+
data= JSON.parse(HTTParty.get("http://aws.amazon.com/ec2/pricing/json/#{AWSCosts::EC2::TYPE_MAPPING[type]}-od.json").body)
|
38
|
+
data['config']['regions'].each do |region|
|
39
|
+
platforms = {}
|
40
|
+
region['instanceTypes'].each do |instance_type|
|
41
|
+
type = instance_type['type']
|
42
|
+
instance_type['sizes'].each do |instance_size|
|
43
|
+
size = instance_size['size']
|
44
|
+
platform_cost = Hash.new({})
|
45
|
+
instance_size['valueColumns'].each do |value|
|
46
|
+
platform_cost[value['name']] = value['prices']['USD'].to_f
|
47
|
+
end
|
48
|
+
|
49
|
+
platform_cost.each_pair do |p,v|
|
50
|
+
platforms[p] = {} unless platforms.key?(p)
|
51
|
+
platforms[p][TYPE_TRANSLATION["#{type}.#{size}"]] = v
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
result[region['region']] = platforms
|
56
|
+
end
|
57
|
+
result
|
58
|
+
end
|
59
|
+
self.new(type, raw_data[region])
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
def self.cache
|
64
|
+
@@cache ||= {}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'json'
|
3
|
+
class AWSCosts::EC2ReservedInstances
|
4
|
+
|
5
|
+
TERMS = { one_year: 'yrTerm1', three_year: 'yrTerm3' }
|
6
|
+
|
7
|
+
TYPE_TRANSLATION = { 'stdResI.sm' => 'm1.small',
|
8
|
+
'stdResI.med' => 'm1.medium',
|
9
|
+
'stdResI.lg' => 'm1.large',
|
10
|
+
'stdResI.xl' => 'm1.xlarge',
|
11
|
+
'secgenstdResI.xl' => 'm3.xlarge',
|
12
|
+
'secgenstdResI.xxl' => 'm3.2xlarge',
|
13
|
+
'uResI.u' => 't1.micro',
|
14
|
+
'hiMemResI.xl' => 'm2.xlarge',
|
15
|
+
'hiMemResI.xxl' => 'm2.2xlarge',
|
16
|
+
'hiMemResI.xxxxl' => 'm2.4xlarge',
|
17
|
+
'hiCPUResI.med' => 'c1.medium',
|
18
|
+
'hiCPUResI.xl' => 'c1.xlarge',
|
19
|
+
'clusterComputeI.xxxxl' => 'cc1.4xlarge',
|
20
|
+
'clusterComputeI.xxxxxxxxl' => 'cc2.8xlarge',
|
21
|
+
'clusterGPUI.xxxxl' => 'cg1.4xlarge',
|
22
|
+
'clusterHiMemResI.xxxxxxxxl' => 'cr1.8xlarge',
|
23
|
+
'hiStoreResI.xxxxxxxxl' => 'hs1.8xlarge',
|
24
|
+
'hiIoResI.xxxxl' => 'hi1.4xlarge' }
|
25
|
+
def initialize data
|
26
|
+
@data= data
|
27
|
+
end
|
28
|
+
|
29
|
+
def upfront term, size=nil
|
30
|
+
if size
|
31
|
+
@data[TERMS[term]][size]
|
32
|
+
else
|
33
|
+
@data[TERMS[term]]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def hourly term, size=nil
|
38
|
+
if size
|
39
|
+
@data["#{TERMS[term]}Hourly"][size]
|
40
|
+
else
|
41
|
+
@data["#{TERMS[term]}Hourly"][size]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def self.fetch type, utilisation, region
|
47
|
+
raw_data= cache[type] ||= begin
|
48
|
+
result = {}
|
49
|
+
data= JSON.parse(HTTParty.get("http://aws.amazon.com/ec2/pricing/json/#{AWSCosts::EC2::TYPES[type]}-ri-#{utilisation}.json").body)
|
50
|
+
data['config']['regions'].each do |region|
|
51
|
+
platforms = {}
|
52
|
+
region['instanceTypes'].each do |instance_type|
|
53
|
+
type = instance_type['type']
|
54
|
+
instance_type['sizes'].each do |instance_size|
|
55
|
+
size = instance_size['size']
|
56
|
+
platform_cost = Hash.new({})
|
57
|
+
|
58
|
+
instance_size['valueColumns'].each do |value|
|
59
|
+
platform_cost[value['name']] = value['prices']['USD']
|
60
|
+
end
|
61
|
+
|
62
|
+
platform_cost.each_pair do |p,v|
|
63
|
+
platforms[p] = {} unless platforms.key?(p)
|
64
|
+
platforms[p][TYPE_TRANSLATION["#{type}.#{size}"]] = v
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
result[region['region']] = platforms
|
69
|
+
end
|
70
|
+
result
|
71
|
+
end
|
72
|
+
self.new(raw_data[region])
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
private
|
77
|
+
def self.cache
|
78
|
+
@@cache ||= {}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
class AWSCosts::Region
|
3
|
+
|
4
|
+
attr_reader :name, :full_name, :price_mapping
|
5
|
+
|
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
|
+
'ap-southeast-1' => { :full_name => 'Asia Pacific (Singapore)', :price_mapping => 'apac-sin' },
|
12
|
+
'ap-southeast-2' => { :full_name => 'Asia Pacific (Sydney)', :price_mapping => 'apac-syd' },
|
13
|
+
'ap-northeast-1' => { :full_name => 'Asia Pacific (Tokyo)', :price_mapping => 'apac-tokyo' },
|
14
|
+
'sa-east-1' => { :full_name => 'South America (Sao Paulo)', :price_mapping => 'sa-east-1' }
|
15
|
+
}
|
16
|
+
|
17
|
+
def self.find name
|
18
|
+
SUPPORTED[name] ? self.new(name) : nil
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def ec2
|
23
|
+
AWSCosts::EC2.new(self)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
private
|
28
|
+
def initialize name
|
29
|
+
@name = name
|
30
|
+
@full_name = SUPPORTED[name][:full_name]
|
31
|
+
@price_mapping = SUPPORTED[name][:price_mapping]
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/lib/awscosts.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AWSCosts::Region do
|
4
|
+
|
5
|
+
subject { AWSCosts::Region.find('us-east-1') }
|
6
|
+
|
7
|
+
it { should respond_to(:name) }
|
8
|
+
it { should respond_to(:full_name) }
|
9
|
+
|
10
|
+
describe '.find' do
|
11
|
+
|
12
|
+
describe 'for a supported region' do
|
13
|
+
it 'should be an instance of Region' do
|
14
|
+
subject.should be_a(AWSCosts::Region)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
describe 'for an unsupported region' do
|
18
|
+
it 'should return nothing' do
|
19
|
+
AWSCosts::Region.find('NotValid').should be_nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '.ec2' do
|
25
|
+
it 'should be an instance of EC2' do
|
26
|
+
subject.ec2.should be_a(AWSCosts::EC2)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: awscosts
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Stephen Bartlett
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-05-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: httparty
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.11.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.11.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.3'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.3'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: AWSCosts provides an easier way to calculate the costs of running your
|
79
|
+
project in AWS
|
80
|
+
email:
|
81
|
+
- stephenb@rtlett.org
|
82
|
+
executables: []
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- .gitignore
|
87
|
+
- Gemfile
|
88
|
+
- LICENSE.txt
|
89
|
+
- README.md
|
90
|
+
- Rakefile
|
91
|
+
- awscosts.gemspec
|
92
|
+
- lib/awscosts.rb
|
93
|
+
- lib/awscosts/ec2.rb
|
94
|
+
- lib/awscosts/ec2_elb.rb
|
95
|
+
- lib/awscosts/ec2_on_demand.rb
|
96
|
+
- lib/awscosts/ec2_reserved_instances.rb
|
97
|
+
- lib/awscosts/region.rb
|
98
|
+
- lib/awscosts/version.rb
|
99
|
+
- spec/awscosts/ec2_spec.rb
|
100
|
+
- spec/awscosts/region_spec.rb
|
101
|
+
- spec/spec_helper.rb
|
102
|
+
homepage: https://github.com/srbartlett/awscosts
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
require_paths:
|
108
|
+
- lib
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
segments:
|
116
|
+
- 0
|
117
|
+
hash: 4440165124257606433
|
118
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ! '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
segments:
|
125
|
+
- 0
|
126
|
+
hash: 4440165124257606433
|
127
|
+
requirements: []
|
128
|
+
rubyforge_project:
|
129
|
+
rubygems_version: 1.8.23
|
130
|
+
signing_key:
|
131
|
+
specification_version: 3
|
132
|
+
summary: Programmatic access to AWS pricing
|
133
|
+
test_files:
|
134
|
+
- spec/awscosts/ec2_spec.rb
|
135
|
+
- spec/awscosts/region_spec.rb
|
136
|
+
- spec/spec_helper.rb
|