cloudcost 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +8 -0
- data/Rakefile +14 -0
- data/lib/cloudcost/api_connection.rb +5 -1
- data/lib/cloudcost/cli.rb +5 -3
- data/lib/cloudcost/commands/server.rb +2 -1
- data/lib/cloudcost/commands/volume/volume.rb +2 -4
- data/lib/cloudcost/commands/volume/volume_influxdb_output.rb +37 -0
- data/lib/cloudcost/commands/volume/volume_list.rb +15 -9
- data/lib/cloudcost/commands/volume.rb +3 -1
- data/lib/cloudcost/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e1f7c30aba80a09bbcd150df43e48d0d7dfa47bd14460634e6997d451957d5f9
|
4
|
+
data.tar.gz: f0f628f8ffbc0f7cdcc08e9882758b11392b159e5293671ca0f24cd3a507ec68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4bf7307e6baca20b673899a5729106114e6933e7a719022350ba9c2a14724b98b1b625503d1015d052279dfe5e2b029567dbfd7089207565ababe3cdd359ef67
|
7
|
+
data.tar.gz: d3abdac8948c4e93a9df63458018b390f1c1ea6d92a2365e1b99d93de973c862989f6dfca797fe3008e1796790a137c98b644bf9809fe1ed5c6f3b2535af8ae6
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -192,3 +192,11 @@ Filter volumes by names:
|
|
192
192
|
```sh
|
193
193
|
cloudcost volumes --name "pvc"
|
194
194
|
```
|
195
|
+
|
196
|
+
Output as InfluxDB Line Protocol:
|
197
|
+
|
198
|
+
```sh
|
199
|
+
cloudcost volumes --output influx --profile prod --no-attached
|
200
|
+
```
|
201
|
+
|
202
|
+
NOTE: The Line Protocol output includes a tag `state` which is either "attached", "unattached" or "all".
|
data/Rakefile
CHANGED
@@ -6,3 +6,17 @@ require "rubocop/rake_task"
|
|
6
6
|
RuboCop::RakeTask.new
|
7
7
|
|
8
8
|
task default: %i[rubocop]
|
9
|
+
|
10
|
+
DOCKER_REGISTRY = "registry.puzzle.ch/puzzle/cloudcost"
|
11
|
+
|
12
|
+
desc "Build the docker image and tag it with the current version."
|
13
|
+
task :docker_build do
|
14
|
+
puts command = "docker build -t #{DOCKER_REGISTRY}:#{Cloudcost::VERSION} ."
|
15
|
+
puts `#{command}`
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Push the newest docker image."
|
19
|
+
task :docker_push do
|
20
|
+
puts command = "docker push #{DOCKER_REGISTRY}:#{Cloudcost::VERSION}"
|
21
|
+
puts `#{command}`
|
22
|
+
end
|
@@ -44,7 +44,11 @@ module Cloudcost
|
|
44
44
|
volumes = volumes.reject { |volume| volume[:tags].key?(options[:missing_tag].to_sym) } if options[:missing_tag]
|
45
45
|
volumes = volumes.select { |volume| /#{options[:name]}/.match? volume[:name] } if options[:name]
|
46
46
|
volumes = volumes.select { |volume| /#{options[:type]}/.match? volume[:type] } if options[:type]
|
47
|
-
|
47
|
+
unless options[:attached].nil?
|
48
|
+
volumes = volumes.select do |volume|
|
49
|
+
(volume[:servers].size.positive?) == options[:attached]
|
50
|
+
end
|
51
|
+
end
|
48
52
|
volumes
|
49
53
|
end
|
50
54
|
|
data/lib/cloudcost/cli.rb
CHANGED
@@ -96,7 +96,7 @@ module Cloudcost
|
|
96
96
|
option :summary, desc: "display totals only", type: :boolean, aliases: %w[-S]
|
97
97
|
option :type, enum: %w[ssd bulk], desc: "volume type"
|
98
98
|
option :attached, type: :boolean, desc: "volume attached to servers"
|
99
|
-
option :output, default: "table", enum: %w[table csv], desc: "output format", aliases: %w[-o]
|
99
|
+
option :output, default: "table", enum: %w[table csv influx], desc: "output format", aliases: %w[-o]
|
100
100
|
def volumes
|
101
101
|
volumes = load_volumes(options)
|
102
102
|
if options[:output] == "table"
|
@@ -154,7 +154,7 @@ module Cloudcost
|
|
154
154
|
end
|
155
155
|
|
156
156
|
def output_servers(servers, options)
|
157
|
-
if servers.
|
157
|
+
if servers.empty?
|
158
158
|
yield "WARNING: No servers found."
|
159
159
|
elsif options[:group_by]
|
160
160
|
yield Cloudcost::ServerList.new(servers, options).grouped_costs
|
@@ -170,10 +170,12 @@ module Cloudcost
|
|
170
170
|
end
|
171
171
|
|
172
172
|
def output_volumes(volumes, options)
|
173
|
-
if volumes.
|
173
|
+
if volumes.empty?
|
174
174
|
yield "WARNING: No volumes found."
|
175
175
|
elsif options[:output] == "csv"
|
176
176
|
yield Cloudcost::VolumeList.new(volumes, options).to_csv
|
177
|
+
elsif options[:output] == "influx"
|
178
|
+
yield Cloudcost::VolumeList.new(volumes, options).totals_influx_line_protocol
|
177
179
|
else
|
178
180
|
yield Cloudcost::VolumeList.new(volumes, options).cost_table
|
179
181
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
require_relative "server/server_tabular_output"
|
3
4
|
require_relative "server/server_influxdb_output"
|
4
5
|
require_relative "csv_output"
|
5
6
|
require_relative "server/server"
|
6
|
-
require_relative "server/server_list"
|
7
|
+
require_relative "server/server_list"
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Cloudcost
|
4
|
-
|
5
4
|
# Representation of cloudscale.ch volume object
|
6
5
|
class Volume
|
7
6
|
attr_accessor :data
|
@@ -27,11 +26,11 @@ module Cloudcost
|
|
27
26
|
end
|
28
27
|
|
29
28
|
def server_name
|
30
|
-
servers.size
|
29
|
+
servers.size.positive? ? servers.first[:name] : ""
|
31
30
|
end
|
32
31
|
|
33
32
|
def attached?
|
34
|
-
servers.size
|
33
|
+
servers.size.positive?
|
35
34
|
end
|
36
35
|
|
37
36
|
def server_uuids
|
@@ -53,6 +52,5 @@ module Cloudcost
|
|
53
52
|
def costs_per_day
|
54
53
|
Pricing.storage_costs_per_day(type, size_gb)
|
55
54
|
end
|
56
|
-
|
57
55
|
end
|
58
56
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudcost
|
4
|
+
# InfluxDB output methods for the ServerList class
|
5
|
+
module VolumeInfluxdbOutput
|
6
|
+
def totals_influx_line_protocol
|
7
|
+
lines = []
|
8
|
+
tag_set = [
|
9
|
+
"profile=#{@options[:profile] || "?"}",
|
10
|
+
"state=#{volumes_attached_state}"
|
11
|
+
]
|
12
|
+
metrics = calculate_totals
|
13
|
+
[
|
14
|
+
{ field: "ssd_gb", key: :size_ssd, unit: "i" },
|
15
|
+
{ field: "bulk_gb", key: :size_bulk, unit: "i" },
|
16
|
+
{ field: "chf_per_day", key: :size, unit: "" }
|
17
|
+
].each do |field|
|
18
|
+
lines << %(
|
19
|
+
cloudscaleVolumeCosts,#{tag_set.join(",")}
|
20
|
+
#{field[:field]}=#{metrics[field[:key]]}#{field[:unit]}
|
21
|
+
).gsub(/\s+/, " ").strip
|
22
|
+
end
|
23
|
+
lines.join("\n")
|
24
|
+
end
|
25
|
+
|
26
|
+
def volumes_attached_state
|
27
|
+
case @options[:attached]
|
28
|
+
when true
|
29
|
+
"attached"
|
30
|
+
when false
|
31
|
+
"unattached"
|
32
|
+
else
|
33
|
+
"all"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -5,8 +5,8 @@ require "terminal-table"
|
|
5
5
|
module Cloudcost
|
6
6
|
# volumeList represents a list of volumes and integrates several output methods
|
7
7
|
class VolumeList
|
8
|
-
|
9
8
|
include Cloudcost::CsvOutput
|
9
|
+
include Cloudcost::VolumeInfluxdbOutput
|
10
10
|
|
11
11
|
def initialize(volumes, options = {})
|
12
12
|
@volumes = volumes
|
@@ -14,9 +14,10 @@ module Cloudcost
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def calculate_totals(volumes = @volumes)
|
17
|
-
total = { size: 0, cost: 0.0 }
|
17
|
+
total = { size: 0, size_ssd: 0, size_bulk: 0, cost: 0.0 }
|
18
18
|
volumes.each do |volume|
|
19
19
|
total[:size] += volume.size_gb
|
20
|
+
total["size_#{volume.type}".to_sym] += volume.size_gb if %w[ssd bulk].include? volume.type
|
20
21
|
total[:cost] += volume.costs_per_day
|
21
22
|
end
|
22
23
|
total
|
@@ -25,8 +26,16 @@ module Cloudcost
|
|
25
26
|
def totals(volumes = @volumes)
|
26
27
|
total = calculate_totals(volumes)
|
27
28
|
total_row = @options[:summary] ? %w[Total] : ["Total", "", "", "", ""]
|
29
|
+
if @options[:summary]
|
30
|
+
total_row.concat [
|
31
|
+
total[:size_ssd],
|
32
|
+
total[:size_bulk],
|
33
|
+
total[:size]
|
34
|
+
]
|
35
|
+
else
|
36
|
+
total_row.concat [total[:size]]
|
37
|
+
end
|
28
38
|
total_row.concat [
|
29
|
-
total[:size],
|
30
39
|
format("%.2f", total[:cost].round(2)),
|
31
40
|
format("%.2f", (total[:cost] * 30).round(2))
|
32
41
|
]
|
@@ -34,13 +43,11 @@ module Cloudcost
|
|
34
43
|
|
35
44
|
def headings
|
36
45
|
headings = if @options[:summary]
|
37
|
-
[""]
|
38
|
-
elsif @options[:group_by]
|
39
|
-
%w[Group Volumes]
|
46
|
+
["", "SSD [GB]", "Bulk [GB]", "Total [GB]"]
|
40
47
|
else
|
41
|
-
|
48
|
+
["Name", "UUID", "Type", "Servers", "Tags", "Size [GB]"]
|
42
49
|
end
|
43
|
-
headings.concat ["
|
50
|
+
headings.concat ["CHF/day", "CHF/30-days"]
|
44
51
|
end
|
45
52
|
|
46
53
|
def rows
|
@@ -74,6 +81,5 @@ module Cloudcost
|
|
74
81
|
(first_number_row..table.columns.size).each { |column| table.align_column(column, :right) }
|
75
82
|
table
|
76
83
|
end
|
77
|
-
|
78
84
|
end
|
79
85
|
end
|
data/lib/cloudcost/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudcost
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nik Wolfgramm
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: excon
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- lib/cloudcost/commands/server/server_tabular_output.rb
|
111
111
|
- lib/cloudcost/commands/volume.rb
|
112
112
|
- lib/cloudcost/commands/volume/volume.rb
|
113
|
+
- lib/cloudcost/commands/volume/volume_influxdb_output.rb
|
113
114
|
- lib/cloudcost/commands/volume/volume_list.rb
|
114
115
|
- lib/cloudcost/error.rb
|
115
116
|
- lib/cloudcost/pricing.rb
|