radfish 0.1.6 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a8cc83490b7562ec8aba8b5b477ff5b544ac13b5e0bb11c2213a9306c73ce724
4
- data.tar.gz: 0aaa19bf9e17a85ca8f825f6260880795fc177a98dd6db8de55c0e49effa1078
3
+ metadata.gz: 5b04f4c83ffefc35a7faaa8793ca8c7fdc6c9eea300d1f9d21ae9b0e3a1cc93a
4
+ data.tar.gz: 4dcf1830e6510676f6b45014b339a5767a6de9ba73d444d107adb31a87e255a6
5
5
  SHA512:
6
- metadata.gz: 5ee9bfeaf78e836cf5faff02ffe9b4f2058a87166eef954a2cc5a6a0469277b06475e229c858cbf5084ab6a8b6b40381018bfea4aca0fe5297140c86ef1472bd
7
- data.tar.gz: 887f6b6ce8f38d3c69b5af446f700a2ab01cb3aa8bfa42316d23077e1d01ea74badee4f097503abf015facc70c785d745f0132f50a188bd9765028b77ffbab9c
6
+ metadata.gz: f9b99bdc943bf4915c6f2b94ee1e37ae04e368e71f8f022ece2322b47c890bd4532b54dd9401ce2b71a9f3d678c2b04c5704c136328f27225403b90af715110a
7
+ data.tar.gz: 22be0c17c6b71173d7e01ccdbbe049375035a98909cb76639d8a1ef414507847ca780d95f36df23556a9b924cba3519a6b2d531efa82d076252a5e3ac48da2f5
data/README.md CHANGED
@@ -129,7 +129,9 @@ radfish system [OPTIONS] # Display system information
129
129
  radfish cpus [OPTIONS] # List CPUs
130
130
  radfish memory [OPTIONS] # List memory modules
131
131
  radfish nics [OPTIONS] # List network interfaces
132
- radfish drives [OPTIONS] # List storage drives
132
+ radfish storage controllers # List storage controllers
133
+ radfish storage drives # List drives across controllers
134
+ radfish storage volumes # List volumes across controllers
133
135
  radfish psus [OPTIONS] # List power supplies
134
136
  ```
135
137
 
@@ -361,7 +363,8 @@ info = client.system_info
361
363
  client.cpus # CPU information
362
364
  client.memory # Memory DIMMs
363
365
  client.nics # Network interfaces
364
- client.drives # Physical drives
366
+ client.controllers.each { |c| c.drives } # Physical drives (per controller)
367
+ client.controllers.each { |c| c.volumes } # RAID volumes (per controller)
365
368
  client.psus # Power supplies
366
369
  ```
367
370
 
data/lib/radfish/cli.rb CHANGED
@@ -342,32 +342,76 @@ module Radfish
342
342
  data = client.storage_summary
343
343
  output_result(data, nil) if options[:json]
344
344
  when 'controllers'
345
- data = client.storage_controllers
346
- output_result(data, nil) if options[:json]
347
- unless options[:json]
345
+ ctrls = client.controllers
346
+ if options[:json]
347
+ puts JSON.pretty_generate(ctrls.map(&:to_h))
348
+ else
348
349
  puts "=== Storage Controllers ===".green
349
- data.each do |ctrl|
350
- puts "#{ctrl['name']} (#{ctrl['id']})".cyan
350
+ ctrls.each do |ctrl|
351
+ puts "#{ctrl.name || 'Controller'} (#{ctrl.id})".cyan
351
352
  end
352
353
  end
353
354
  when 'drives', 'disks'
354
- data = client.drives
355
+ # Get all drives from all controllers
356
+ controllers = client.controllers
357
+ all_drives = []
358
+
359
+ controllers.each do |controller|
360
+ begin
361
+ drives = controller.drives
362
+ all_drives.concat(drives) if drives
363
+ rescue => e
364
+ ctrl_name = controller.respond_to?(:name) ? controller.name : 'controller'
365
+ puts "Error fetching drives for #{ctrl_name}: #{e.message}".yellow if options[:verbose]
366
+ end
367
+ end
368
+
355
369
  if options[:json]
356
- puts JSON.pretty_generate(data)
370
+ puts JSON.pretty_generate(all_drives)
357
371
  else
358
372
  puts "=== Physical Drives ===".green
359
- data.each do |drive|
360
- puts "#{drive['name']}: #{drive['capacity_gb']} GB - #{drive['status']}".cyan
373
+ if all_drives.empty?
374
+ puts "No drives found".yellow
375
+ else
376
+ all_drives.each do |drive|
377
+ cert_status = drive['certified'] || drive.certified rescue nil
378
+ cert_info = cert_status ? " [Certified: #{cert_status}]" : ""
379
+ capacity = drive['capacity_gb'] || drive.capacity_gb rescue "Unknown"
380
+ status = drive['status'] || drive.status rescue "Unknown"
381
+ name = drive['name'] || drive.name rescue "Unknown"
382
+ puts "#{name}: #{capacity} GB - #{status}#{cert_info}".cyan
383
+ end
361
384
  end
362
385
  end
363
386
  when 'volumes', 'raids'
364
- data = client.volumes
387
+ # Get all volumes from all controllers
388
+ controllers = client.controllers
389
+ all_volumes = []
390
+
391
+ controllers.each do |controller|
392
+ begin
393
+ volumes = controller.volumes
394
+ all_volumes.concat(volumes) if volumes
395
+ rescue => e
396
+ ctrl_name = controller.respond_to?(:name) ? controller.name : 'controller'
397
+ puts "Error fetching volumes for #{ctrl_name}: #{e.message}".yellow if options[:verbose]
398
+ end
399
+ end
400
+
365
401
  if options[:json]
366
- puts JSON.pretty_generate(data)
402
+ puts JSON.pretty_generate(all_volumes)
367
403
  else
368
404
  puts "=== Volumes ===".green
369
- data.each do |vol|
370
- puts "#{vol['name']}: #{vol['capacity_gb']} GB - #{vol['raid_type']}".cyan
405
+ if all_volumes.empty?
406
+ puts "No volumes found".yellow
407
+ else
408
+ all_volumes.each do |vol|
409
+ name = vol['name'] || vol.name rescue "Unknown"
410
+ capacity = vol['capacity_gb'] || vol.capacity_gb rescue "Unknown"
411
+ raid_type = vol['raid_type'] || vol.raid_type rescue "Unknown"
412
+ status = vol['status'] || vol.status rescue "Unknown"
413
+ puts "#{name}: #{capacity} GB - #{raid_type} (Status: #{status})".cyan
414
+ end
371
415
  end
372
416
  end
373
417
  else
@@ -795,7 +839,10 @@ module Radfish
795
839
  puts "\n=== Power Supplies ===".green
796
840
  data.each do |psu|
797
841
  status_color = psu['status'] == 'OK' ? :green : :red
798
- puts "#{psu['name']}: #{psu['watts']}W - #{psu['status']}".send(status_color)
842
+ voltage_info = psu['voltage'] ? "#{psu['voltage']}V (#{psu['voltage_human'] || 'Unknown'})" : ""
843
+ puts "#{psu['name']}: #{voltage_info} #{psu['watts']}W - #{psu['status']}".send(status_color)
844
+ puts " Model: #{psu['model']}" if psu['model']
845
+ puts " Serial: #{psu['serial']}" if psu['serial']
799
846
  end
800
847
  end
801
848
  end
@@ -821,4 +868,4 @@ module Radfish
821
868
  end
822
869
  end
823
870
  end
824
- end
871
+ end
@@ -165,5 +165,40 @@ module Radfish
165
165
  base_url: @adapter.base_url
166
166
  }
167
167
  end
168
+
169
+ # Storage convenience API
170
+ # Return normalized Controller objects while keeping adapter APIs intact.
171
+ def controllers
172
+ raw = @adapter.storage_controllers
173
+ Array(raw).map { |c| build_controller(c) }
174
+ end
175
+
176
+ # Public storage API (not backward-compatible): require a Controller object.
177
+ def drives(controller)
178
+ raise ArgumentError, "Controller required" unless controller.is_a?(Controller)
179
+ @adapter.drives(controller)
180
+ end
181
+
182
+ def volumes(controller)
183
+ raise ArgumentError, "Controller required" unless controller.is_a?(Controller)
184
+ @adapter.volumes(controller)
185
+ end
186
+
187
+ private
188
+
189
+ def build_controller(raw)
190
+ # Only extract friendly name/id if plainly available; keep raw in adapter_data
191
+ id = if raw.respond_to?(:[])
192
+ raw['id'] || raw[:id]
193
+ elsif raw.respond_to?(:id)
194
+ raw.id
195
+ end
196
+ name = if raw.respond_to?(:[])
197
+ raw['name'] || raw[:name]
198
+ elsif raw.respond_to?(:name)
199
+ raw.name
200
+ end
201
+ Controller.new(client: self, id: id, name: name, vendor: @vendor, adapter_data: raw)
202
+ end
168
203
  end
169
- end
204
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Radfish
4
+ # Lightweight value object representing a storage controller.
5
+ # Holds a stable identifier and optional name.
6
+ class Controller
7
+ attr_reader :id, :name, :vendor, :adapter_data
8
+
9
+ def initialize(client:, id:, name: nil, vendor: nil, adapter_data: nil)
10
+ @client = client
11
+ @id = id
12
+ @name = name
13
+ @vendor = vendor
14
+ @adapter_data = adapter_data
15
+ end
16
+
17
+ # Convenience accessors delegate to the client wrappers
18
+ def drives
19
+ @client.drives(self)
20
+ end
21
+
22
+ def volumes
23
+ @client.volumes(self)
24
+ end
25
+
26
+ def to_h
27
+ { id: id, name: name, vendor: vendor }
28
+ end
29
+
30
+ def ==(other)
31
+ other.is_a?(Controller) && other.id == id && other.vendor.to_s == vendor.to_s
32
+ end
33
+ end
34
+ end
@@ -7,12 +7,12 @@ module Radfish
7
7
  raise NotImplementedError, "Adapter must implement #storage_controllers"
8
8
  end
9
9
 
10
- def drives
11
- raise NotImplementedError, "Adapter must implement #drives"
10
+ def drives(controller)
11
+ raise NotImplementedError, "Adapter must implement #drives(controller)"
12
12
  end
13
13
 
14
- def volumes
15
- raise NotImplementedError, "Adapter must implement #volumes"
14
+ def volumes(controller)
15
+ raise NotImplementedError, "Adapter must implement #volumes(controller)"
16
16
  end
17
17
 
18
18
  def storage_summary
@@ -20,4 +20,4 @@ module Radfish
20
20
  end
21
21
  end
22
22
  end
23
- end
23
+ end
@@ -62,7 +62,7 @@ module Radfish
62
62
  end
63
63
 
64
64
  def controllers
65
- @cache[:controllers] ||= @client.adapter.storage_controllers
65
+ @cache[:controllers] ||= @client.controllers
66
66
  end
67
67
 
68
68
  private
@@ -71,4 +71,4 @@ module Radfish
71
71
  @cache[:system_info] ||= @client.adapter.system_info
72
72
  end
73
73
  end
74
- end
74
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Radfish
4
- VERSION = "0.1.6"
5
- end
4
+ VERSION = "0.2.0"
5
+ end
data/lib/radfish.rb CHANGED
@@ -92,6 +92,7 @@ require_relative 'radfish/bmc_info'
92
92
  require_relative 'radfish/power_info'
93
93
  require_relative 'radfish/thermal_info'
94
94
  require_relative 'radfish/pci_info'
95
+ require_relative 'radfish/controller'
95
96
  require_relative 'radfish/client'
96
97
 
97
98
  # Auto-load adapters if available
@@ -105,4 +106,4 @@ begin
105
106
  require 'radfish/supermicro_adapter'
106
107
  rescue LoadError
107
108
  # radfish-supermicro gem not installed
108
- end
109
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: radfish
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Siegel
@@ -169,6 +169,7 @@ files:
169
169
  - lib/radfish/cli.rb
170
170
  - lib/radfish/cli/base.rb
171
171
  - lib/radfish/client.rb
172
+ - lib/radfish/controller.rb
172
173
  - lib/radfish/core/base_client.rb
173
174
  - lib/radfish/core/boot.rb
174
175
  - lib/radfish/core/jobs.rb