ec2spec 0.1.2 → 0.1.3
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/CHANGELOG.md +10 -0
- data/Gemfile.lock +10 -1
- data/README.md +109 -23
- data/ec2spec.gemspec +6 -3
- data/lib/ec2spec.rb +8 -0
- data/lib/ec2spec/calculator/api_price_calculator.rb +34 -0
- data/lib/ec2spec/calculator/manual_price_calculator.rb +9 -0
- data/lib/ec2spec/cli.rb +20 -2
- data/lib/ec2spec/client.rb +30 -16
- data/lib/ec2spec/formatter.rb +5 -0
- data/lib/ec2spec/formatter/hash_formatter.rb +13 -0
- data/lib/ec2spec/formatter/json_formatter.rb +14 -0
- data/lib/ec2spec/formatter/markdown_formatter.rb +15 -0
- data/lib/ec2spec/formatter/plain_text_formatter.rb +27 -0
- data/lib/ec2spec/formatter/slack_formatter.rb +13 -0
- data/lib/ec2spec/host_result.rb +32 -5
- data/lib/ec2spec/initializer.rb +21 -0
- data/lib/ec2spec/offer_index_file.rb +2 -11
- data/lib/ec2spec/price_calculator.rb +51 -3
- data/lib/ec2spec/version.rb +1 -1
- metadata +44 -9
- data/lib/ec2spec/hash_formatter.rb +0 -11
- data/lib/ec2spec/json_formatter.rb +0 -12
- data/lib/ec2spec/plain_text_formatter.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60150ecbe0bd1b6478aa68c3cd15b31e105ecd6c
|
4
|
+
data.tar.gz: 3456da709faf5d462df6944cb3a9de7428b4d0bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4209d90cdf962bf9ab747c07d2737faafc7375396af3df633a482c308163ca1780f3a32e0ebeba15a4eefddd0498a3c6e62464e41c3090b031e736ee2e6c693
|
7
|
+
data.tar.gz: 4c3770534df422645520e5c4504698dd95063eb4579e5a429f77dbc976e033590dfcc61ec075efac9e4706ae6777e2ad84fd20efeedd88dea38bd03f10f4505c
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.1.3
|
4
|
+
|
5
|
+
### Added
|
6
|
+
* Add logo
|
7
|
+
* Support currency unit price output by API/Manual
|
8
|
+
* Support markdown/slack format
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
* Output error messages when connecting host error was raised
|
12
|
+
|
3
13
|
## 0.1.2
|
4
14
|
|
5
15
|
### Added
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ec2spec (0.1.
|
4
|
+
ec2spec (0.1.3)
|
5
5
|
faraday
|
6
|
+
money
|
7
|
+
money-open-exchange-rates
|
6
8
|
specinfra
|
7
9
|
terminal-table
|
8
10
|
thor
|
@@ -11,10 +13,17 @@ GEM
|
|
11
13
|
remote: https://rubygems.org/
|
12
14
|
specs:
|
13
15
|
ast (2.4.0)
|
16
|
+
concurrent-ruby (1.0.5)
|
14
17
|
diff-lcs (1.3)
|
15
18
|
faraday (0.15.2)
|
16
19
|
multipart-post (>= 1.2, < 3)
|
20
|
+
i18n (1.0.1)
|
21
|
+
concurrent-ruby (~> 1.0)
|
17
22
|
jaro_winkler (1.5.1)
|
23
|
+
money (6.12.0)
|
24
|
+
i18n (>= 0.6.4, < 1.1)
|
25
|
+
money-open-exchange-rates (1.2.2)
|
26
|
+
money (~> 6.6)
|
18
27
|
multipart-post (2.0.0)
|
19
28
|
net-scp (1.2.1)
|
20
29
|
net-ssh (>= 2.6.5)
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# ec2spec
|
1
|
+
# [](https://github.com/kyoshidajp/ec2spec)
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/ec2spec)
|
4
4
|
[](https://travis-ci.org/kyoshidajp/ec2spec)
|
@@ -32,6 +32,30 @@ $ gem install ec2spec
|
|
32
32
|
$ ec2spec ssh -h host1 ... [options]
|
33
33
|
```
|
34
34
|
|
35
|
+
### Example
|
36
|
+
|
37
|
+
```
|
38
|
+
$ ec2spec ssh -h host1 host2 host3
|
39
|
+
I, [2018-08-12T20:54:25.814752 #64341] INFO -- : Started: host1
|
40
|
+
I, [2018-08-12T20:54:25.814835 #64341] INFO -- : Started: host2
|
41
|
+
I, [2018-08-12T20:54:25.814867 #64341] INFO -- : Started: host3
|
42
|
+
E, [2018-08-12T20:54:25.826113 #64341] ERROR -- : Connection refused: host3
|
43
|
+
I, [2018-08-12T20:54:29.385848 #64341] INFO -- : Finished: host1
|
44
|
+
I, [2018-08-12T20:54:37.560003 #64341] INFO -- : Finished: host2
|
45
|
+
+---------------+-------------+---------------------+-------+
|
46
|
+
| | host1 | host2 | host3 |
|
47
|
+
+---------------+-------------+---------------------|-------+
|
48
|
+
| instance_type | t2.micro | c4.2xlarge | N/A |
|
49
|
+
| instance_id | i-xxxxxxxx | i-yyyyyyyy | N/A |
|
50
|
+
| vCPU | 1 | 8 | N/A |
|
51
|
+
| memory | 1 GiB | 15 GiB | N/A |
|
52
|
+
| price (USD/H) | 0.0152 | 0.504 | N/A |
|
53
|
+
| price (USD/M) | 11.3088 | 374.976 | N/A |
|
54
|
+
+---------------+-------------+---------------------+-------+
|
55
|
+
```
|
56
|
+
|
57
|
+
The data of `host3` could not be acquired due to a connection refused error.
|
58
|
+
|
35
59
|
### Options
|
36
60
|
|
37
61
|
```
|
@@ -40,39 +64,101 @@ $ ec2spec ssh -h host1 ... [options]
|
|
40
64
|
--days How many days per one month.
|
41
65
|
|
42
66
|
--format Output format (default: plain_text).
|
43
|
-
plain_text, json, hash
|
67
|
+
plain_text, json, hash, slack, markdown
|
44
68
|
|
45
69
|
--region Region of EC2 (default: ap-northeast-1).
|
46
70
|
|
71
|
+
--unit Currency unit.
|
72
|
+
with --rate.
|
73
|
+
|
74
|
+
--rate Dollar exchange rate.
|
75
|
+
with --unit.
|
76
|
+
|
77
|
+
--calc_type Calculate exchange currency rate type.
|
78
|
+
api, manual
|
79
|
+
with --app_id, --unit (if app)
|
80
|
+
--unit, rate (if manual)
|
81
|
+
|
82
|
+
--app_id App ID of Open Exchange Rates
|
83
|
+
https://openexchangerates.org/
|
84
|
+
with --calc_type, --unit
|
85
|
+
|
47
86
|
--debug Output logs as DEBUG level.
|
48
87
|
```
|
49
88
|
|
50
|
-
|
89
|
+
#### --format (`plain_text`)
|
51
90
|
|
52
91
|
```
|
53
|
-
|
92
|
+
+---------------+-------------+-------------+
|
93
|
+
| | host1 | host2 |
|
94
|
+
+---------------+-------------+-------------|
|
95
|
+
| instance_type | t2.micro | c4.2xlarge |
|
96
|
+
| instance_id | i-xxxxxxxx | i-yyyyyyyy |
|
97
|
+
| vCPU | 1 | 8 |
|
98
|
+
| memory | 1 GiB | 15 GiB |
|
99
|
+
| price (USD/H) | 0.0152 | 0.504 |
|
100
|
+
| price (USD/M) | 11.3088 | 374.976 |
|
101
|
+
+---------------+-------------+-------------+
|
54
102
|
```
|
55
103
|
|
104
|
+
#### --format (`json` and `hash`)
|
105
|
+
|
56
106
|
```
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
| price (USD/
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
107
|
+
{"host1":{"instance_type":"t2.micro","instance_id":"i-xxxxxxxx","vCPU":"1","memory":"1 GiB","price (USD/H)":0.0152,"price (USD/M)":11.3088},"host2":{"instance_type":"c4.2xlarge","instance_id":"i-yyyyyyyy","vCPU":"8","memory":"15 GiB","price (USD/H)":0.504,"price (USD/M)":374.976}}
|
108
|
+
```
|
109
|
+
|
110
|
+
#### --format (`slack`)
|
111
|
+
|
112
|
+
````
|
113
|
+
```
|
114
|
+
+---------------+-------------+-------------+
|
115
|
+
| | host1 | host2 |
|
116
|
+
+---------------+-------------+-------------+
|
117
|
+
| instance_type | t2.micro | c4.2xlarge |
|
118
|
+
| instance_id | i-xxxxxxxx | i-yyyyyyyy |
|
119
|
+
| vCPU | 1 | 8 |
|
120
|
+
| memory | 1 GiB | 15 GiB |
|
121
|
+
| price (USD/H) | 0.0152 | 0.504 |
|
122
|
+
| price (USD/M) | 11.3088 | 374.976 |
|
123
|
+
+---------------+-------------+-------------+
|
124
|
+
```
|
125
|
+
````
|
126
|
+
|
127
|
+
#### --format (`markdown`)
|
128
|
+
|
129
|
+
```
|
130
|
+
| | stg-bastion | worker1 |
|
131
|
+
|---------------|-------------|-------------|
|
132
|
+
| instance_type | t2.micro | c4.2xlarge |
|
133
|
+
| instance_id | i-xxxxxxxx | i-yyyyyyyy |
|
134
|
+
| vCPU | 1 | 8 |
|
135
|
+
| memory | 1 GiB | 15 GiB |
|
136
|
+
| price (USD/H) | 0.0152 | 0.504 |
|
137
|
+
| price (USD/M) | 11.3088 | 374.976 |
|
138
|
+
```
|
139
|
+
|
140
|
+
### Exchange currency rate
|
141
|
+
|
142
|
+
#### Manual
|
143
|
+
|
144
|
+
Output JPY as exchange rate is 1 dollar 111 yen.
|
145
|
+
|
146
|
+
```
|
147
|
+
$ ec2spec ssh -h host1 host2 --unit JPY --calc_type manual
|
148
|
+
```
|
149
|
+
|
150
|
+
#### API
|
151
|
+
|
152
|
+
First, get App ID from
|
153
|
+
https://openexchangerates.org/
|
154
|
+
|
155
|
+
Output JPY with it.
|
156
|
+
|
157
|
+
```
|
158
|
+
$ ec2spec ssh -h host1 host2 --unit JPY --calc_type api --app_id xxxxxxxx
|
159
|
+
```
|
160
|
+
|
161
|
+
**Note:** Exchange rate is cached in `~/.ec2spec/oxr.json`. If you want to refresh, you have to delete it.
|
76
162
|
|
77
163
|
## As a library
|
78
164
|
|
data/ec2spec.gemspec
CHANGED
@@ -4,11 +4,12 @@ require 'ec2spec/version'
|
|
4
4
|
Gem::Specification.new do |spec|
|
5
5
|
spec.name = 'ec2spec'
|
6
6
|
spec.version = Ec2spec::VERSION
|
7
|
-
spec.authors = %w[Katsuhiko YOSHIDA]
|
7
|
+
spec.authors = %w["Katsuhiko YOSHIDA"]
|
8
8
|
spec.email = %w[claddvd@gmail.com]
|
9
9
|
|
10
|
-
spec.
|
11
|
-
|
10
|
+
spec.description = 'ec2spec is a simple comparison tool '\
|
11
|
+
'for Amazon EC2 Instances you can access.'
|
12
|
+
spec.summary = spec.description
|
12
13
|
spec.homepage = 'https://github.com/kyoshidajp/ec2spec'
|
13
14
|
spec.license = 'MIT'
|
14
15
|
|
@@ -20,6 +21,8 @@ Gem::Specification.new do |spec|
|
|
20
21
|
spec.require_paths = ['lib']
|
21
22
|
|
22
23
|
spec.add_dependency 'faraday'
|
24
|
+
spec.add_dependency 'money'
|
25
|
+
spec.add_dependency 'money-open-exchange-rates'
|
23
26
|
spec.add_dependency 'specinfra'
|
24
27
|
spec.add_dependency 'terminal-table'
|
25
28
|
spec.add_dependency 'thor'
|
data/lib/ec2spec.rb
CHANGED
@@ -5,9 +5,17 @@ require 'terminal-table'
|
|
5
5
|
require 'ec2spec/cli'
|
6
6
|
require 'ec2spec/client'
|
7
7
|
require 'ec2spec/const'
|
8
|
+
require 'ec2spec/formatter'
|
9
|
+
require 'ec2spec/initializer'
|
8
10
|
require 'ec2spec/version'
|
9
11
|
require 'ec2spec/host_result'
|
10
12
|
require 'ec2spec/logger'
|
11
13
|
require 'ec2spec/offer_file'
|
12
14
|
require 'ec2spec/offer_index_file'
|
13
15
|
require 'ec2spec/price_calculator'
|
16
|
+
|
17
|
+
module Ec2spec
|
18
|
+
def self.project_dir
|
19
|
+
File.join(ENV['HOME'], Const::PROJECT_DIR)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'money'
|
2
|
+
require 'money/bank/open_exchange_rates_bank'
|
3
|
+
|
4
|
+
module Ec2spec
|
5
|
+
module Calculator
|
6
|
+
module ApiPriceCalculator
|
7
|
+
OXR_CACHE = 'oxr.json'
|
8
|
+
|
9
|
+
def currency_unit
|
10
|
+
@currency_unit
|
11
|
+
end
|
12
|
+
|
13
|
+
def currency_unit_price(dollar_price)
|
14
|
+
Money.new(dollar_price * 100, :USD).exchange_to(currency_unit)
|
15
|
+
end
|
16
|
+
|
17
|
+
def cache_file
|
18
|
+
File.join(Ec2spec.project_dir, OXR_CACHE)
|
19
|
+
end
|
20
|
+
|
21
|
+
def prepare_exchange_api(app_id)
|
22
|
+
prepare_money(app_id)
|
23
|
+
end
|
24
|
+
|
25
|
+
def prepare_money(app_id)
|
26
|
+
oxr = Money::Bank::OpenExchangeRatesBank.new
|
27
|
+
oxr.app_id = app_id
|
28
|
+
oxr.cache = cache_file
|
29
|
+
oxr.update_rates
|
30
|
+
Money.default_bank = oxr
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/ec2spec/cli.rb
CHANGED
@@ -5,21 +5,39 @@ module Ec2spec
|
|
5
5
|
desc 'ssh -h host1 ...', 'Compare the specifications of EC2 instances.'
|
6
6
|
option 'host', aliases: 'h', type: :array, equired: true
|
7
7
|
option 'days', type: :numeric
|
8
|
+
option 'rate', type: :numeric
|
9
|
+
option 'unit'
|
8
10
|
option 'format'
|
9
11
|
option 'region'
|
12
|
+
option 'app_id'
|
13
|
+
option 'calc_type'
|
10
14
|
option 'debug', type: :boolean
|
11
15
|
|
12
|
-
# rubocop:disable Metrics/AbcSize
|
16
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
13
17
|
def ssh
|
14
18
|
hosts = options['host']
|
15
19
|
days = options['days']
|
20
|
+
rate = options['rate']
|
21
|
+
unit = options['unit']
|
22
|
+
app_id = options['app_id']
|
23
|
+
calc_type = options['calc_type']
|
16
24
|
format = options['format'] || :plain_text
|
17
25
|
region = options['region'] || 'ap-northeast-1'
|
18
26
|
|
19
27
|
Ec2spec.logger.level = Logger::DEBUG if options['debug']
|
20
28
|
client = Ec2spec::Client.new(hosts, days, format, region)
|
29
|
+
if exchange_unit?(unit, rate, app_id)
|
30
|
+
client.prepare_price_calculator(unit, rate,
|
31
|
+
calc_type, app_id)
|
32
|
+
end
|
21
33
|
puts client.run
|
22
34
|
end
|
23
|
-
# rubocop:enable Metrics/AbcSize
|
35
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def exchange_unit?(unit, rate, app_id)
|
40
|
+
(rate || app_id) && unit
|
41
|
+
end
|
24
42
|
end
|
25
43
|
end
|
data/lib/ec2spec/client.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
require 'ec2spec/
|
2
|
-
require 'ec2spec/
|
3
|
-
require 'ec2spec/hash_formatter'
|
1
|
+
require 'ec2spec/formatter'
|
2
|
+
require 'ec2spec/price_calculator'
|
4
3
|
|
5
4
|
module Ec2spec
|
6
5
|
class UndefineFormatterError < StandardError; end
|
@@ -12,9 +11,17 @@ module Ec2spec
|
|
12
11
|
DEFAULT_REGION = 'ap-northeast-1'
|
13
12
|
|
14
13
|
OUTPUT_FORMATTERS = {
|
15
|
-
plain_text: PlainTextFormatter,
|
16
|
-
json:
|
17
|
-
hash:
|
14
|
+
plain_text: Formatter::PlainTextFormatter,
|
15
|
+
json: Formatter::JsonFormatter,
|
16
|
+
hash: Formatter::HashFormatter,
|
17
|
+
slack: Formatter::SlackFormatter,
|
18
|
+
markdown: Formatter::MarkdownFormatter,
|
19
|
+
}
|
20
|
+
|
21
|
+
CONNECTION_ERROR_WITH_MESSAGES = {
|
22
|
+
Errno::ECONNREFUSED => 'Connection refused: %{host}',
|
23
|
+
Net::SSH::ConnectionTimeout => 'Connection timeout: %{host}',
|
24
|
+
StandardError => 'Unknown error: %{host}',
|
18
25
|
}
|
19
26
|
|
20
27
|
def initialize(hosts, days, format, region = DEFAULT_REGION)
|
@@ -23,8 +30,13 @@ module Ec2spec
|
|
23
30
|
@format = format
|
24
31
|
@region = region
|
25
32
|
|
33
|
+
Initializer.instance.do(region)
|
34
|
+
|
26
35
|
extend_formatter
|
27
|
-
|
36
|
+
end
|
37
|
+
|
38
|
+
def prepare_price_calculator(unit, rate, calc_type, app_id = nil)
|
39
|
+
PriceCalculator.instance.prepare(unit, rate, calc_type, app_id)
|
28
40
|
end
|
29
41
|
|
30
42
|
def run
|
@@ -51,17 +63,19 @@ module Ec2spec
|
|
51
63
|
extend OUTPUT_FORMATTERS[format_sym]
|
52
64
|
end
|
53
65
|
|
66
|
+
def host_result(host, backend)
|
67
|
+
Ec2spec.logger.info("Finished: #{host.host}")
|
68
|
+
host.instance_type = instance_type(backend)
|
69
|
+
host.instance_id = instance_id(backend)
|
70
|
+
rescue *CONNECTION_ERROR_WITH_MESSAGES.keys => e
|
71
|
+
message = format(CONNECTION_ERROR_WITH_MESSAGES[e.class], host: host.host)
|
72
|
+
Ec2spec.logger.error(message)
|
73
|
+
host.na_values
|
74
|
+
end
|
75
|
+
|
54
76
|
def exec_host_result(host, backend)
|
55
77
|
Ec2spec.logger.info("Started: #{host.host}")
|
56
|
-
|
57
|
-
begin
|
58
|
-
host.instance_type = instance_type(backend)
|
59
|
-
host.instance_id = instance_id(backend)
|
60
|
-
rescue Errno::ECONNREFUSED
|
61
|
-
host.na_values
|
62
|
-
end
|
63
|
-
|
64
|
-
Ec2spec.logger.info("Finished: #{host.host}")
|
78
|
+
host_result(host, backend)
|
65
79
|
host
|
66
80
|
end
|
67
81
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'ec2spec/formatter/plain_text_formatter'
|
2
|
+
|
3
|
+
module Ec2spec
|
4
|
+
module Formatter
|
5
|
+
module MarkdownFormatter
|
6
|
+
include Ec2spec::Formatter::PlainTextFormatter
|
7
|
+
|
8
|
+
def output(results, _hosts)
|
9
|
+
table = super
|
10
|
+
table.style = { border_i: '|', border_top: false, border_bottom: false }
|
11
|
+
table
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Ec2spec
|
2
|
+
module Formatter
|
3
|
+
module PlainTextFormatter
|
4
|
+
def output(results, hosts)
|
5
|
+
table = Terminal::Table.new
|
6
|
+
table.headings = table_header(results)
|
7
|
+
table.rows = table_rows(results)
|
8
|
+
column_count = hosts.size + 1
|
9
|
+
column_count.times { |i| table.align_column(i, :right) }
|
10
|
+
table
|
11
|
+
end
|
12
|
+
|
13
|
+
def table_header(results)
|
14
|
+
[''].concat(results.map(&:host))
|
15
|
+
end
|
16
|
+
|
17
|
+
def table_rows(results)
|
18
|
+
Ec2spec::HostResult.label_with_methods
|
19
|
+
.each_with_object([]) do |(k, v), row|
|
20
|
+
unit = PriceCalculator.instance.currency_unit
|
21
|
+
label = format(k, unit)
|
22
|
+
row << [label].concat(results.map(&v))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/ec2spec/host_result.rb
CHANGED
@@ -2,6 +2,7 @@ module Ec2spec
|
|
2
2
|
class HostResult
|
3
3
|
MONTH_OF_DAYS = 31
|
4
4
|
NA_VALUE = 'N/A'
|
5
|
+
NUMBER_OF_DECIMAL_PLACES = 3
|
5
6
|
|
6
7
|
LABEL_WITH_METHODS = {
|
7
8
|
'instance_type' => :instance_type,
|
@@ -12,9 +13,18 @@ module Ec2spec
|
|
12
13
|
'price (USD/M)' => :price_per_month,
|
13
14
|
}
|
14
15
|
|
15
|
-
attr_accessor :host, :backend, :instance_id
|
16
|
+
attr_accessor :host, :backend, :instance_id
|
16
17
|
attr_reader :instance_type
|
17
|
-
attr_writer :price_per_unit
|
18
|
+
attr_writer :price_per_unit, :vcpu
|
19
|
+
|
20
|
+
def self.label_with_methods
|
21
|
+
label_methods = LABEL_WITH_METHODS
|
22
|
+
if PriceCalculator.instance.currency_values?
|
23
|
+
label_methods['price (%s/H)'] = :price_per_currency_unit
|
24
|
+
label_methods['price (%s/M)'] = :price_per_currency_unit_month
|
25
|
+
end
|
26
|
+
label_methods
|
27
|
+
end
|
18
28
|
|
19
29
|
def initialize(region, host, days = nil)
|
20
30
|
@region = region
|
@@ -27,7 +37,7 @@ module Ec2spec
|
|
27
37
|
@instance_type = NA_VALUE
|
28
38
|
@instance_id = NA_VALUE
|
29
39
|
@memory = NA_VALUE
|
30
|
-
@
|
40
|
+
@vcpu = NA_VALUE
|
31
41
|
@price_per_unit = NA_VALUE
|
32
42
|
end
|
33
43
|
|
@@ -53,11 +63,26 @@ module Ec2spec
|
|
53
63
|
Ec2spec::OfferFile.instance.price_per_unit(@instance_type)
|
54
64
|
end
|
55
65
|
|
66
|
+
def price_per_currency_unit
|
67
|
+
return @price_per_currency_unit unless @price_per_currency_unit.nil?
|
68
|
+
|
69
|
+
dollar_price = Ec2spec::OfferFile.instance.price_per_unit(@instance_type)
|
70
|
+
@price_per_currency_unit = PriceCalculator
|
71
|
+
.instance.currency_unit_price(dollar_price)
|
72
|
+
@price_per_currency_unit.fractional.floor(NUMBER_OF_DECIMAL_PLACES).to_f
|
73
|
+
end
|
74
|
+
|
56
75
|
def price_per_month
|
57
76
|
return NA_VALUE if @price_per_unit == NA_VALUE
|
58
77
|
@price_per_unit * 24 * @days
|
59
78
|
end
|
60
79
|
|
80
|
+
def price_per_currency_unit_month
|
81
|
+
return NA_VALUE if @price_per_currency_unit == NA_VALUE
|
82
|
+
(@price_per_currency_unit * 24 * @days)
|
83
|
+
.fractional.floor(NUMBER_OF_DECIMAL_PLACES).to_f
|
84
|
+
end
|
85
|
+
|
61
86
|
def to_hash
|
62
87
|
host_values
|
63
88
|
end
|
@@ -65,8 +90,10 @@ module Ec2spec
|
|
65
90
|
private
|
66
91
|
|
67
92
|
def host_values
|
68
|
-
|
69
|
-
|
93
|
+
self.class.label_with_methods.each_with_object({}) do |(k, v), hash|
|
94
|
+
unit = PriceCalculator.instance.currency_unit
|
95
|
+
label = format(k, unit)
|
96
|
+
hash[label] = public_send(v)
|
70
97
|
end
|
71
98
|
end
|
72
99
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module Ec2spec
|
4
|
+
class Initializer
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
def do(region)
|
8
|
+
mkdir_project_dir
|
9
|
+
OfferFile.instance.prepare(region)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def mkdir_project_dir
|
15
|
+
return if Dir.exist?(Ec2spec.project_dir)
|
16
|
+
|
17
|
+
Dir.mkdir(Ec2spec.project_dir)
|
18
|
+
Ec2spec.logger.debug("Created project dir: #{Ec2spec.project_dir}")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -7,7 +7,6 @@ module Ec2spec
|
|
7
7
|
REGION_INDEX_FILE_URL = 'https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/region_index.json'
|
8
8
|
|
9
9
|
def offer_file_url(region)
|
10
|
-
mkdir_project_dir
|
11
10
|
offer_index_file_json
|
12
11
|
|
13
12
|
file_path = @offer_index_file_json['regions'][region]['currentVersionUrl']
|
@@ -18,21 +17,13 @@ module Ec2spec
|
|
18
17
|
|
19
18
|
private
|
20
19
|
|
21
|
-
def project_dir
|
22
|
-
File.join(ENV['HOME'], Const::PROJECT_DIR)
|
23
|
-
end
|
24
|
-
|
25
|
-
def mkdir_project_dir
|
26
|
-
Dir.mkdir(project_dir) unless Dir.exist?(project_dir)
|
27
|
-
end
|
28
|
-
|
29
20
|
def region_index_file_path
|
30
|
-
File.join(project_dir, REGION_INDEX_FILE_URL)
|
21
|
+
File.join(Ec2spec.project_dir, REGION_INDEX_FILE_URL)
|
31
22
|
end
|
32
23
|
|
33
24
|
def offer_index_file_path
|
34
25
|
file_name = File.basename(REGION_INDEX_FILE_URL)
|
35
|
-
File.join(project_dir, file_name)
|
26
|
+
File.join(Ec2spec.project_dir, file_name)
|
36
27
|
end
|
37
28
|
|
38
29
|
def offer_index_file_json
|
@@ -1,9 +1,57 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'ec2spec/calculator/api_price_calculator'
|
3
|
+
require 'ec2spec/calculator/manual_price_calculator'
|
4
|
+
|
1
5
|
module Ec2spec
|
6
|
+
class UndefinedCalcError < StandardError; end
|
7
|
+
class ApiKeyError < StandardError; end
|
8
|
+
|
2
9
|
class PriceCalculator
|
3
|
-
|
4
|
-
|
10
|
+
include Singleton
|
11
|
+
|
12
|
+
attr_accessor :currency_unit, :dollar_exchange_rate
|
13
|
+
|
14
|
+
PRICE_CALCULATORS = {
|
15
|
+
manual: Calculator::ManualPriceCalculator,
|
16
|
+
api: Calculator::ApiPriceCalculator,
|
17
|
+
}
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@currency_unit = nil
|
21
|
+
@dollar_exchange_rate = nil
|
22
|
+
@app_id = nil
|
5
23
|
end
|
6
24
|
|
7
|
-
def
|
25
|
+
def prepare(unit, rate, calc_type = :manual, app_id = nil)
|
26
|
+
@currency_unit = unit
|
27
|
+
@dollar_exchange_rate = rate
|
28
|
+
@app_id = app_id
|
29
|
+
@calc_type = calc_type
|
30
|
+
|
31
|
+
extend_calc
|
32
|
+
|
33
|
+
Money.infinite_precision = true
|
34
|
+
raise ApiKeyError if calc_type_sym == :api && app_id.nil?
|
35
|
+
prepare_exchange_api(app_id) if calc_type_sym == :api
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def currency_values?
|
40
|
+
!@currency_unit.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def extend_calc
|
46
|
+
raise UndefinedCalcError unless PRICE_CALCULATORS.key?(calc_type_sym)
|
47
|
+
extend PRICE_CALCULATORS[calc_type_sym]
|
48
|
+
Ec2spec.logger.debug("Calculate price: #{@calc_type}")
|
49
|
+
end
|
50
|
+
|
51
|
+
def calc_type_sym
|
52
|
+
@calc_type.to_sym
|
53
|
+
rescue NoMethodError
|
54
|
+
raise UndefinedCalcError
|
55
|
+
end
|
8
56
|
end
|
9
57
|
end
|
data/lib/ec2spec/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ec2spec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Katsuhiko
|
8
|
-
- YOSHIDA
|
7
|
+
- "\"Katsuhiko"
|
8
|
+
- YOSHIDA"
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-08-
|
12
|
+
date: 2018-08-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|
@@ -25,6 +25,34 @@ dependencies:
|
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: money
|
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: money-open-exchange-rates
|
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'
|
28
56
|
- !ruby/object:Gem::Dependency
|
29
57
|
name: specinfra
|
30
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,7 +151,8 @@ dependencies:
|
|
123
151
|
- - ">="
|
124
152
|
- !ruby/object:Gem::Version
|
125
153
|
version: '0'
|
126
|
-
description:
|
154
|
+
description: ec2spec is a simple comparison tool for Amazon EC2 Instances you can
|
155
|
+
access.
|
127
156
|
email:
|
128
157
|
- claddvd@gmail.com
|
129
158
|
executables:
|
@@ -148,16 +177,22 @@ files:
|
|
148
177
|
- exe/ec2spec
|
149
178
|
- exe/setup
|
150
179
|
- lib/ec2spec.rb
|
180
|
+
- lib/ec2spec/calculator/api_price_calculator.rb
|
181
|
+
- lib/ec2spec/calculator/manual_price_calculator.rb
|
151
182
|
- lib/ec2spec/cli.rb
|
152
183
|
- lib/ec2spec/client.rb
|
153
184
|
- lib/ec2spec/const.rb
|
154
|
-
- lib/ec2spec/
|
185
|
+
- lib/ec2spec/formatter.rb
|
186
|
+
- lib/ec2spec/formatter/hash_formatter.rb
|
187
|
+
- lib/ec2spec/formatter/json_formatter.rb
|
188
|
+
- lib/ec2spec/formatter/markdown_formatter.rb
|
189
|
+
- lib/ec2spec/formatter/plain_text_formatter.rb
|
190
|
+
- lib/ec2spec/formatter/slack_formatter.rb
|
155
191
|
- lib/ec2spec/host_result.rb
|
156
|
-
- lib/ec2spec/
|
192
|
+
- lib/ec2spec/initializer.rb
|
157
193
|
- lib/ec2spec/logger.rb
|
158
194
|
- lib/ec2spec/offer_file.rb
|
159
195
|
- lib/ec2spec/offer_index_file.rb
|
160
|
-
- lib/ec2spec/plain_text_formatter.rb
|
161
196
|
- lib/ec2spec/price_calculator.rb
|
162
197
|
- lib/ec2spec/version.rb
|
163
198
|
homepage: https://github.com/kyoshidajp/ec2spec
|
@@ -183,5 +218,5 @@ rubyforge_project:
|
|
183
218
|
rubygems_version: 2.6.14.1
|
184
219
|
signing_key:
|
185
220
|
specification_version: 4
|
186
|
-
summary:
|
221
|
+
summary: ec2spec is a simple comparison tool for Amazon EC2 Instances you can access.
|
187
222
|
test_files: []
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module Ec2spec
|
2
|
-
module PlainTextFormatter
|
3
|
-
def output(results, hosts)
|
4
|
-
table = Terminal::Table.new
|
5
|
-
table.headings = table_header(results)
|
6
|
-
table.rows = table_rows(results)
|
7
|
-
column_count = hosts.size + 1
|
8
|
-
column_count.times { |i| table.align_column(i, :right) }
|
9
|
-
table
|
10
|
-
end
|
11
|
-
|
12
|
-
def table_header(results)
|
13
|
-
[''].concat(results.map(&:host))
|
14
|
-
end
|
15
|
-
|
16
|
-
def table_rows(results)
|
17
|
-
Ec2spec::HostResult::LABEL_WITH_METHODS
|
18
|
-
.each_with_object([]) do |(k, v), row|
|
19
|
-
row << [k].concat(results.map(&v))
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|