ec2spec 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 35066b282c5961b31b00bf8a976e97731c3706b2
4
+ data.tar.gz: 80caf94e7fdf60f3b5c71fc74eab364fa46b2fac
5
+ SHA512:
6
+ metadata.gz: e9695d9a7d836f44b13e18fec1dc517a77db27c3414beb23027674d47156b8f7d89e501423607414ef9fbed825675e6bd3dad4fd2c5ec828a04bc1fecb577b31
7
+ data.tar.gz: dd1688082ec9690f45c837c3e0dc918e14efb4099f994c2a18cecf6a1d4264a5a0d3bcae078188df76d7b95abbd35c55a591c0b9710a685f4fcecaa7d155aafb
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle
2
+ /vendor/bundle/
3
+ /.idea/
4
+ /.yardoc
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
11
+
12
+ # rspec failure tracking
13
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,14 @@
1
+ Documentation:
2
+ Enabled: false
3
+
4
+ Style/FrozenStringLiteralComment:
5
+ Enabled: false
6
+
7
+ Style/MutableConstant:
8
+ Enabled: false
9
+
10
+ Style/TrailingCommaInArguments:
11
+ Enabled: false
12
+
13
+ Style/TrailingCommaInHashLiteral:
14
+ Enabled: false
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.5
5
+ before_install: gem install bundler -v 1.16.1
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,73 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ec2spec (0.1.1)
5
+ faraday
6
+ specinfra
7
+ terminal-table
8
+ thor
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ ast (2.4.0)
14
+ diff-lcs (1.3)
15
+ faraday (0.15.2)
16
+ multipart-post (>= 1.2, < 3)
17
+ jaro_winkler (1.5.1)
18
+ multipart-post (2.0.0)
19
+ net-scp (1.2.1)
20
+ net-ssh (>= 2.6.5)
21
+ net-ssh (5.0.2)
22
+ net-telnet (0.2.0)
23
+ parallel (1.12.1)
24
+ parser (2.5.1.2)
25
+ ast (~> 2.4.0)
26
+ powerpack (0.1.2)
27
+ rainbow (3.0.0)
28
+ rake (10.5.0)
29
+ rspec (3.7.0)
30
+ rspec-core (~> 3.7.0)
31
+ rspec-expectations (~> 3.7.0)
32
+ rspec-mocks (~> 3.7.0)
33
+ rspec-core (3.7.1)
34
+ rspec-support (~> 3.7.0)
35
+ rspec-expectations (3.7.0)
36
+ diff-lcs (>= 1.2.0, < 2.0)
37
+ rspec-support (~> 3.7.0)
38
+ rspec-mocks (3.7.0)
39
+ diff-lcs (>= 1.2.0, < 2.0)
40
+ rspec-support (~> 3.7.0)
41
+ rspec-support (3.7.1)
42
+ rubocop (0.58.2)
43
+ jaro_winkler (~> 1.5.1)
44
+ parallel (~> 1.10)
45
+ parser (>= 2.5, != 2.5.1.1)
46
+ powerpack (~> 0.1)
47
+ rainbow (>= 2.2.2, < 4.0)
48
+ ruby-progressbar (~> 1.7)
49
+ unicode-display_width (~> 1.0, >= 1.0.1)
50
+ ruby-progressbar (1.9.0)
51
+ sfl (2.3)
52
+ specinfra (2.75.1)
53
+ net-scp
54
+ net-ssh (>= 2.7)
55
+ net-telnet
56
+ sfl
57
+ terminal-table (1.8.0)
58
+ unicode-display_width (~> 1.1, >= 1.1.1)
59
+ thor (0.20.0)
60
+ unicode-display_width (1.4.0)
61
+
62
+ PLATFORMS
63
+ ruby
64
+
65
+ DEPENDENCIES
66
+ bundler (~> 1.16)
67
+ ec2spec!
68
+ rake (~> 10.0)
69
+ rspec (~> 3.0)
70
+ rubocop
71
+
72
+ BUNDLED WITH
73
+ 1.16.1
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 YOSHIDA Katsuhiko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # ec2spec
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/ec2spec`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'ec2spec'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install ec2spec
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/kyoshidajp/ec2spec.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
data/ec2spec.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'ec2spec/version'
4
+
5
+ # rubocop:disable Metrics/BlockLength
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'ec2spec'
8
+ spec.version = Ec2spec::VERSION
9
+ spec.authors = %w[Katsuhiko YOSHIDA]
10
+ spec.email = %w[claddvd@gmail.com]
11
+
12
+ spec.summary = 'Write a short summary, because RubyGems requires one.'
13
+ spec.description = 'Write a longer description or delete this line.'
14
+ spec.homepage = 'https://github.com/kyoshidajp/ec2spec'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = 'exe'
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ['lib']
23
+
24
+ spec.add_dependency 'faraday'
25
+ spec.add_dependency 'specinfra'
26
+ spec.add_dependency 'terminal-table'
27
+ spec.add_dependency 'thor'
28
+
29
+ spec.add_development_dependency 'bundler', '~> 1.16'
30
+ spec.add_development_dependency 'rake', '~> 10.0'
31
+ spec.add_development_dependency 'rspec', '~> 3.0'
32
+ spec.add_development_dependency 'rubocop'
33
+ end
34
+ # rubocop:enable Metrics/BlockLength
data/exe/console ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'ec2spec'
5
+ require 'irb'
6
+ IRB.start(__FILE__)
data/exe/ec2spec ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ec2spec'
4
+
5
+ Ec2spec::CLI.start
data/exe/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/ec2spec.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'specinfra'
2
+ require 'terminal-table'
3
+ require 'ec2spec/cli'
4
+ require 'ec2spec/client'
5
+ require 'ec2spec/version'
6
+ require 'ec2spec/host_result'
7
+ require 'ec2spec/offer_file'
8
+ require 'ec2spec/price_calculator'
@@ -0,0 +1,15 @@
1
+ require 'thor'
2
+
3
+ module Ec2spec
4
+ class CLI < Thor
5
+ desc 'ssh host ...', ''
6
+ option 'host', aliases: 'h', type: :array, equired: true
7
+ option 'days', type: :numeric
8
+ def ssh
9
+ hosts = options['host']
10
+ days = options['days']
11
+ client = Ec2spec::Client.new(hosts, days)
12
+ client.run
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,110 @@
1
+ require 'logger'
2
+
3
+ module Ec2spec
4
+ class Client
5
+ META_DATA_URL_BASE = 'http://169.254.169.254/latest/meta-data/'
6
+ META_DATA_INSTANCE_TYPE_PATH = '/instance-type'
7
+ META_DATA_INSTANCE_ID_PATH = '/instance-id'
8
+
9
+ TABLE_LABEL_WITH_METHODS = {
10
+ 'instance_type' => :instance_type,
11
+ 'instance_id' => :instance_id,
12
+ 'memory' => :memory,
13
+ 'price (USD/H)' => :price_per_unit,
14
+ 'price (USD/M)' => :price_per_month,
15
+ }
16
+
17
+ def initialize(hosts, days)
18
+ @log = Logger.new(STDOUT)
19
+ @log.level = Logger::INFO
20
+
21
+ @hosts = hosts
22
+ @days = days
23
+ end
24
+
25
+ def run
26
+ hosts = @hosts.map { |host| target(host) }
27
+ threads = hosts.map do |host|
28
+ Thread.start(host.backend) do |backend|
29
+ exec_host_result(host, backend)
30
+ end
31
+ end
32
+ @results = threads.each(&:join)
33
+ output
34
+ end
35
+
36
+ private
37
+
38
+ def exec_host_result(host, backend)
39
+ @log.info("Started: #{host.host}")
40
+
41
+ begin
42
+ host.instance_type = instance_type(backend)
43
+ host.instance_id = instance_id(backend)
44
+ host.memory = memory(backend)
45
+ rescue Errno::ECONNREFUSED
46
+ host.na_values
47
+ end
48
+
49
+ @log.info("Finished: #{host.host}")
50
+ host
51
+ end
52
+
53
+ def instance_type(backend)
54
+ cmd_result = backend.run_command(instance_type_cmd)
55
+ cmd_result.stdout
56
+ end
57
+
58
+ def instance_id(backend)
59
+ cmd_result = backend.run_command(instance_id_cmd)
60
+ cmd_result.stdout
61
+ end
62
+
63
+ def metadata_url(path)
64
+ "#{META_DATA_URL_BASE}#{path}"
65
+ end
66
+
67
+ def instance_type_cmd
68
+ "curl -s #{metadata_url(META_DATA_INSTANCE_TYPE_PATH)}"
69
+ end
70
+
71
+ def instance_id_cmd
72
+ "curl -s #{metadata_url(META_DATA_INSTANCE_ID_PATH)}"
73
+ end
74
+
75
+ def memory(backend)
76
+ Specinfra::HostInventory::Memory.new(backend.host_inventory).get['total']
77
+ end
78
+
79
+ def target(host_name)
80
+ ssh_options = Net::SSH::Config.for(host_name)
81
+ backend = Specinfra::Backend::Ssh.new(
82
+ host: ssh_options[:host_name],
83
+ ssh_options: ssh_options,
84
+ )
85
+ host = Ec2spec::HostResult.new(host_name, @days)
86
+ host.backend = backend
87
+ host
88
+ end
89
+
90
+ def output
91
+ results = @results.map(&:value)
92
+ table = Terminal::Table.new
93
+ table.headings = table_header(results)
94
+ table.rows = table_rows(results)
95
+ column_count = @hosts.size + 1
96
+ column_count.times { |i| table.align_column(i, :right) }
97
+ puts table
98
+ end
99
+
100
+ def table_header(results)
101
+ [''].concat(results.map(&:host))
102
+ end
103
+
104
+ def table_rows(results)
105
+ TABLE_LABEL_WITH_METHODS.each_with_object([]) do |(k, v), row|
106
+ row << [k].concat(results.map(&v))
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,41 @@
1
+ module Ec2spec
2
+ class HostResult
3
+ MONTH_OF_DAYS = 31
4
+ NA_VALUE = 'N/A'
5
+
6
+ attr_accessor :host, :backend, :instance_id, :memory, :cpu
7
+ attr_reader :instance_type
8
+ attr_writer :price_per_unit
9
+
10
+ def initialize(host, days = nil)
11
+ @host = host
12
+ @backend = nil
13
+ @days = days || MONTH_OF_DAYS
14
+ end
15
+
16
+ def na_values
17
+ @instance_type = NA_VALUE
18
+ @instance_id = NA_VALUE
19
+ @memory = NA_VALUE
20
+ @cpu = NA_VALUE
21
+ @price_per_unit = NA_VALUE
22
+ end
23
+
24
+ def instance_type=(value)
25
+ @instance_type = value
26
+
27
+ return if value == NA_VALUE
28
+ @offer_file = Ec2spec::OfferFile.new(value)
29
+ price_per_unit
30
+ end
31
+
32
+ def price_per_unit
33
+ @price_per_unit ||= @offer_file.price_per_unit
34
+ end
35
+
36
+ def price_per_month
37
+ return NA_VALUE if @price_per_unit == NA_VALUE
38
+ @price_per_unit * 24 * @days
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,59 @@
1
+ require 'json'
2
+ require 'faraday'
3
+
4
+ module Ec2spec
5
+ class OfferFile
6
+ OFFER_FILE_URL = 'https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/20180802021534/ap-northeast-1/index.json'
7
+ OFFER_FILE_NAME = 'price_list.json'
8
+ OFFER_FILE_DIR = '.ec2spec'
9
+
10
+ def initialize(instance_type)
11
+ @instance_type = instance_type
12
+ @offer_file_json = nil
13
+ end
14
+
15
+ def price_per_unit
16
+ sku_instance_type = sku
17
+ on_demand = offer_file_json['terms']['OnDemand']
18
+ sku_value = on_demand[sku_instance_type].first[1]
19
+ price_dimensions = sku_value['priceDimensions']
20
+ price_dimensions.first[1]['pricePerUnit']['USD'].to_f
21
+ end
22
+
23
+ private
24
+
25
+ def offer_file_json
26
+ download unless File.exist?(offer_file_path)
27
+ @offer_file_json ||= JSON.parse(File.open(offer_file_path).read)
28
+ end
29
+
30
+ def offer_file_path
31
+ price_list_dir = File.join(ENV['HOME'], OFFER_FILE_DIR)
32
+ Dir.mkdir(price_list_dir) unless Dir.exist?(price_list_dir)
33
+ File.join(price_list_dir, OFFER_FILE_NAME)
34
+ end
35
+
36
+ def download
37
+ http_conn = Faraday.new do |builder|
38
+ builder.adapter Faraday.default_adapter
39
+ end
40
+ response = http_conn.get(OFFER_FILE_URL)
41
+ File.open(offer_file_path, 'wb') { |fp| fp.write(response.body) }
42
+ end
43
+
44
+ def sku
45
+ products = offer_file_json['products']
46
+ target_product = products.find do |product|
47
+ product?(product, @instance_type)
48
+ end
49
+ target_product[1]['sku']
50
+ end
51
+
52
+ def product?(product, instance_type)
53
+ attributes = product[1]['attributes']
54
+ attributes['instanceType'] == instance_type &&
55
+ attributes['operatingSystem'] == 'Linux' &&
56
+ attributes['preInstalledSw'] == 'NA'
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,9 @@
1
+ module Ec2spec
2
+ class PriceCalculator
3
+ def initialize(instance_type)
4
+ @instance_type = instance_type
5
+ end
6
+
7
+ def price_per_unit; end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Ec2spec
2
+ VERSION = '0.1.1'
3
+ end
metadata ADDED
@@ -0,0 +1,180 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ec2spec
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Katsuhiko
8
+ - YOSHIDA
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2018-08-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: faraday
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: specinfra
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: terminal-table
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: thor
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: bundler
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '1.16'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '1.16'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rake
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '10.0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '10.0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: rspec
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '3.0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '3.0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: rubocop
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: Write a longer description or delete this line.
127
+ email:
128
+ - claddvd@gmail.com
129
+ executables:
130
+ - console
131
+ - ec2spec
132
+ - setup
133
+ extensions: []
134
+ extra_rdoc_files: []
135
+ files:
136
+ - ".gitignore"
137
+ - ".rspec"
138
+ - ".rubocop.yml"
139
+ - ".travis.yml"
140
+ - Gemfile
141
+ - Gemfile.lock
142
+ - LICENSE
143
+ - README.md
144
+ - Rakefile
145
+ - ec2spec.gemspec
146
+ - exe/console
147
+ - exe/ec2spec
148
+ - exe/setup
149
+ - lib/ec2spec.rb
150
+ - lib/ec2spec/cli.rb
151
+ - lib/ec2spec/client.rb
152
+ - lib/ec2spec/host_result.rb
153
+ - lib/ec2spec/offer_file.rb
154
+ - lib/ec2spec/price_calculator.rb
155
+ - lib/ec2spec/version.rb
156
+ homepage: https://github.com/kyoshidajp/ec2spec
157
+ licenses:
158
+ - MIT
159
+ metadata: {}
160
+ post_install_message:
161
+ rdoc_options: []
162
+ require_paths:
163
+ - lib
164
+ required_ruby_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ required_rubygems_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ requirements: []
175
+ rubyforge_project:
176
+ rubygems_version: 2.6.14.1
177
+ signing_key:
178
+ specification_version: 4
179
+ summary: Write a short summary, because RubyGems requires one.
180
+ test_files: []