cloudcost 0.3.1 → 0.4.0
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/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
|