radfish-idrac 0.1.2 → 0.1.4
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/lib/radfish/idrac/version.rb +1 -1
- data/lib/radfish/idrac_adapter.rb +429 -48
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a58b55f6a0455e66cd44bed5363451e773c675d2a9fd65d7fa5e6bae77669778
|
4
|
+
data.tar.gz: fab0e351a3112e0376b6d065e5faeb6280f7a2dfea90db9d8845bca67e82e4fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05f39a32177f9ef7f07fed8d5911d5a0d6bccaad7d315868895356e645866a39ab6a2a6bb1063349925d82336cc65736ffee6a594dad88e643f501035289e658
|
7
|
+
data.tar.gz: 8e5e9cd3ef3f62d3152b695c35702bccd924df41540bac3434d20182f67c829eee7fa65ccd553ecaf43b75cd9bbbecfef1313269e63a2855aa5b984f831d0178
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'radfish'
|
4
4
|
require 'idrac'
|
5
|
+
require 'ostruct'
|
5
6
|
|
6
7
|
module Radfish
|
7
8
|
class IdracAdapter < Core::BaseClient
|
@@ -12,6 +13,7 @@ module Radfish
|
|
12
13
|
include Core::Boot
|
13
14
|
include Core::Jobs
|
14
15
|
include Core::Utility
|
16
|
+
include Core::Network
|
15
17
|
|
16
18
|
attr_reader :idrac_client
|
17
19
|
|
@@ -62,30 +64,95 @@ module Radfish
|
|
62
64
|
@idrac_client.get_power_state
|
63
65
|
end
|
64
66
|
|
65
|
-
def power_on
|
66
|
-
@idrac_client.power_on
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
67
|
+
def power_on(wait: true)
|
68
|
+
result = @idrac_client.power_on
|
69
|
+
|
70
|
+
if wait && result
|
71
|
+
# Wait for power on to complete
|
72
|
+
max_attempts = 30
|
73
|
+
attempts = 0
|
74
|
+
while attempts < max_attempts
|
75
|
+
sleep 2
|
76
|
+
begin
|
77
|
+
status = power_state
|
78
|
+
break if status == "On"
|
79
|
+
rescue => e
|
80
|
+
# BMC might be temporarily unavailable during power operations
|
81
|
+
debug "Waiting for BMC to respond: #{e.message}", 1, :yellow
|
82
|
+
end
|
83
|
+
attempts += 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
result
|
72
88
|
end
|
73
89
|
|
74
|
-
def
|
75
|
-
#
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
#
|
80
|
-
|
90
|
+
def power_off(type: "GracefulShutdown", wait: true)
|
91
|
+
# Use the type parameter directly - it already uses Redfish standard values
|
92
|
+
result = @idrac_client.power_off(kind: type)
|
93
|
+
|
94
|
+
if wait && result
|
95
|
+
# Wait for power off to complete
|
96
|
+
max_attempts = 30
|
97
|
+
attempts = 0
|
98
|
+
while attempts < max_attempts
|
99
|
+
sleep 2
|
100
|
+
begin
|
101
|
+
status = power_state
|
102
|
+
break if status == "Off"
|
103
|
+
rescue => e
|
104
|
+
# BMC might be temporarily unavailable during power operations
|
105
|
+
debug "Waiting for BMC to respond: #{e.message}", 1, :yellow
|
106
|
+
end
|
107
|
+
attempts += 1
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
result
|
112
|
+
end
|
113
|
+
|
114
|
+
def reboot(type: "GracefulRestart", wait: true)
|
115
|
+
# Use the type parameter - iDRAC's power_off can handle restart types
|
116
|
+
begin
|
117
|
+
result = @idrac_client.power_off(kind: type)
|
118
|
+
rescue => e
|
119
|
+
# If graceful restart fails, fall back to force restart
|
120
|
+
if type == "GracefulRestart"
|
121
|
+
debug "Graceful restart failed, using force restart", 1, :yellow
|
122
|
+
result = @idrac_client.reboot # This is ForceRestart
|
123
|
+
else
|
124
|
+
raise e
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
if wait && result
|
129
|
+
# Wait for system to go down then come back up
|
130
|
+
max_attempts = 60
|
131
|
+
attempts = 0
|
132
|
+
went_down = false
|
133
|
+
|
134
|
+
while attempts < max_attempts
|
135
|
+
sleep 2
|
136
|
+
begin
|
137
|
+
status = power_state
|
138
|
+
went_down = true if status == "Off" && !went_down
|
139
|
+
break if went_down && status == "On"
|
140
|
+
rescue => e
|
141
|
+
# BMC might be temporarily unavailable during reboot
|
142
|
+
debug "Waiting for BMC during reboot: #{e.message}", 1, :yellow
|
143
|
+
end
|
144
|
+
attempts += 1
|
145
|
+
end
|
81
146
|
end
|
147
|
+
|
148
|
+
result
|
82
149
|
end
|
83
150
|
|
84
|
-
def power_cycle
|
85
|
-
#
|
86
|
-
power_off
|
151
|
+
def power_cycle(wait: true)
|
152
|
+
# Power cycle: turn off then on
|
153
|
+
power_off(type: "ForceOff", wait: wait)
|
87
154
|
sleep 5
|
88
|
-
power_on
|
155
|
+
power_on(wait: wait)
|
89
156
|
end
|
90
157
|
|
91
158
|
def reset_type_allowed
|
@@ -96,35 +163,123 @@ module Radfish
|
|
96
163
|
# System information
|
97
164
|
|
98
165
|
def system_info
|
99
|
-
|
166
|
+
# iDRAC gem returns string keys, convert to symbols for radfish
|
167
|
+
info = @idrac_client.system_info
|
168
|
+
|
169
|
+
# Dell servers always have "Dell Inc." as manufacturer
|
170
|
+
# Normalize for consistency
|
171
|
+
manufacturer = "Dell"
|
172
|
+
|
173
|
+
model = info["model"]
|
174
|
+
model = model&.gsub(/^PowerEdge\s+/i, '') if model # Strip PowerEdge prefix
|
175
|
+
|
176
|
+
{
|
177
|
+
service_tag: info["service_tag"],
|
178
|
+
manufacturer: manufacturer,
|
179
|
+
make: manufacturer,
|
180
|
+
model: model,
|
181
|
+
serial: info["service_tag"], # Dell uses service tag as serial
|
182
|
+
serial_number: info["service_tag"],
|
183
|
+
firmware_version: info["firmware_version"],
|
184
|
+
idrac_version: info["idrac_version"],
|
185
|
+
is_dell: info["is_dell"]
|
186
|
+
}.compact
|
187
|
+
end
|
188
|
+
|
189
|
+
# Individual accessor methods for Core::System interface
|
190
|
+
def service_tag
|
191
|
+
@service_tag ||= @idrac_client.system_info["service_tag"]
|
192
|
+
end
|
193
|
+
|
194
|
+
def make
|
195
|
+
"Dell"
|
196
|
+
end
|
197
|
+
|
198
|
+
def model
|
199
|
+
@model ||= begin
|
200
|
+
model = @idrac_client.system_info["model"]
|
201
|
+
model&.gsub(/^PowerEdge\s+/i, '') if model # Strip PowerEdge prefix
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def serial
|
206
|
+
@serial ||= @idrac_client.system_info["service_tag"] # Dell uses service tag as serial
|
100
207
|
end
|
101
208
|
|
102
209
|
def cpus
|
103
|
-
|
210
|
+
# The idrac gem returns a summary hash, but radfish expects an array of CPU objects
|
211
|
+
# For Dell servers, typically all CPUs are identical, so we create objects based on the summary
|
212
|
+
cpu_summary = @idrac_client.cpus
|
213
|
+
|
214
|
+
# Create CPU objects that support dot notation
|
215
|
+
count = cpu_summary["count"] || 0
|
216
|
+
return [] if count == 0
|
217
|
+
|
218
|
+
# For each CPU socket, create an object
|
219
|
+
# Dell typically has identical CPUs, so we use the summary data for each
|
220
|
+
(1..count).map do |socket_num|
|
221
|
+
OpenStruct.new(
|
222
|
+
socket: socket_num,
|
223
|
+
manufacturer: "Intel", # Dell servers typically use Intel
|
224
|
+
model: cpu_summary["model"],
|
225
|
+
speed_mhz: nil, # Not provided in summary
|
226
|
+
cores: cpu_summary["cores"] ? (cpu_summary["cores"] / count) : nil,
|
227
|
+
threads: cpu_summary["threads"] ? (cpu_summary["threads"] / count) : nil,
|
228
|
+
health: cpu_summary["status"]
|
229
|
+
)
|
230
|
+
end
|
104
231
|
end
|
105
232
|
|
106
233
|
def memory
|
107
|
-
@idrac_client.memory
|
234
|
+
mem_data = @idrac_client.memory
|
235
|
+
return [] unless mem_data
|
236
|
+
|
237
|
+
# Convert to OpenStruct for dot notation access
|
238
|
+
mem_data.map { |m| OpenStruct.new(m) }
|
108
239
|
end
|
109
240
|
|
110
241
|
def nics
|
111
|
-
@idrac_client.nics
|
242
|
+
nic_data = @idrac_client.nics
|
243
|
+
return [] unless nic_data
|
244
|
+
|
245
|
+
# Convert to OpenStruct for dot notation access, including nested ports
|
246
|
+
nic_data.map do |nic|
|
247
|
+
if nic["ports"]
|
248
|
+
nic["ports"] = nic["ports"].map { |port| OpenStruct.new(port) }
|
249
|
+
end
|
250
|
+
OpenStruct.new(nic)
|
251
|
+
end
|
112
252
|
end
|
113
253
|
|
114
254
|
def fans
|
115
|
-
|
255
|
+
# Convert hash array to OpenStruct objects for dot notation access
|
256
|
+
fan_data = @idrac_client.fans
|
257
|
+
|
258
|
+
fan_data.map do |fan|
|
259
|
+
OpenStruct.new(fan)
|
260
|
+
end
|
116
261
|
end
|
117
262
|
|
118
263
|
def temperatures
|
119
|
-
|
264
|
+
# iDRAC doesn't provide a dedicated temperatures method
|
265
|
+
# Return empty array to satisfy the interface
|
266
|
+
[]
|
120
267
|
end
|
121
268
|
|
122
269
|
def psus
|
123
|
-
|
270
|
+
# Convert hash array to OpenStruct objects for dot notation access
|
271
|
+
psu_data = @idrac_client.psus
|
272
|
+
|
273
|
+
psu_data.map do |psu|
|
274
|
+
OpenStruct.new(psu)
|
275
|
+
end
|
124
276
|
end
|
125
277
|
|
126
278
|
def power_consumption
|
127
|
-
|
279
|
+
# Return a hash with power consumption data for radfish
|
280
|
+
{
|
281
|
+
consumed_watts: @idrac_client.get_power_usage_watts
|
282
|
+
}
|
128
283
|
end
|
129
284
|
|
130
285
|
def power_consumption_watts
|
@@ -134,7 +289,17 @@ module Radfish
|
|
134
289
|
# Storage
|
135
290
|
|
136
291
|
def storage_controllers
|
137
|
-
|
292
|
+
# Convert hash array to OpenStruct objects for dot notation access
|
293
|
+
# Note: idrac gem uses 'controllers' not 'storage_controllers'
|
294
|
+
controller_data = @idrac_client.controllers
|
295
|
+
|
296
|
+
controller_data.map do |controller|
|
297
|
+
# Convert drives array to OpenStruct objects if present
|
298
|
+
if controller["drives"]
|
299
|
+
controller["drives"] = controller["drives"].map { |drive| OpenStruct.new(drive) }
|
300
|
+
end
|
301
|
+
OpenStruct.new(controller)
|
302
|
+
end
|
138
303
|
end
|
139
304
|
|
140
305
|
def drives
|
@@ -155,12 +320,41 @@ module Radfish
|
|
155
320
|
@idrac_client.virtual_media
|
156
321
|
end
|
157
322
|
|
158
|
-
def insert_virtual_media(iso_url, device:
|
323
|
+
def insert_virtual_media(iso_url, device: nil)
|
324
|
+
# Default to "CD" for iDRAC if not specified
|
325
|
+
device ||= "CD"
|
159
326
|
@idrac_client.insert_virtual_media(iso_url, device: device)
|
327
|
+
rescue Idrac::Error => e
|
328
|
+
# Translate iDRAC errors to Radfish errors with context
|
329
|
+
error_message = e.message
|
330
|
+
|
331
|
+
if error_message.include?("connection refused") || error_message.include?("unreachable")
|
332
|
+
raise Radfish::VirtualMediaConnectionError, "BMC cannot reach ISO server: #{error_message}"
|
333
|
+
elsif error_message.include?("already attached") || error_message.include?("in use")
|
334
|
+
raise Radfish::VirtualMediaBusyError, "Virtual media device busy: #{error_message}"
|
335
|
+
elsif error_message.include?("not found") || error_message.include?("does not exist")
|
336
|
+
raise Radfish::VirtualMediaNotFoundError, "Virtual media device not found: #{error_message}"
|
337
|
+
elsif error_message.include?("timeout")
|
338
|
+
raise Radfish::TaskTimeoutError, "Virtual media operation timed out: #{error_message}"
|
339
|
+
else
|
340
|
+
# Generic virtual media error
|
341
|
+
raise Radfish::VirtualMediaError, error_message
|
342
|
+
end
|
343
|
+
rescue StandardError => e
|
344
|
+
# Catch any other errors and wrap them
|
345
|
+
raise Radfish::VirtualMediaError, "Virtual media insertion failed: #{e.message}"
|
160
346
|
end
|
161
347
|
|
162
348
|
def eject_virtual_media(device: "CD")
|
163
349
|
@idrac_client.eject_virtual_media(device: device)
|
350
|
+
rescue Idrac::Error => e
|
351
|
+
if e.message.include?("not found") || e.message.include?("does not exist")
|
352
|
+
raise Radfish::VirtualMediaNotFoundError, "Virtual media device not found: #{e.message}"
|
353
|
+
else
|
354
|
+
raise Radfish::VirtualMediaError, "Failed to eject virtual media: #{e.message}"
|
355
|
+
end
|
356
|
+
rescue StandardError => e
|
357
|
+
raise Radfish::VirtualMediaError, "Failed to eject virtual media: #{e.message}"
|
164
358
|
end
|
165
359
|
|
166
360
|
def virtual_media_status
|
@@ -187,12 +381,24 @@ module Radfish
|
|
187
381
|
|
188
382
|
# Boot configuration
|
189
383
|
|
384
|
+
def boot_config
|
385
|
+
# Return hash for consistent data structure
|
386
|
+
@idrac_client.boot_config
|
387
|
+
end
|
388
|
+
|
389
|
+
# Shorter alias for convenience
|
390
|
+
def boot
|
391
|
+
boot_config
|
392
|
+
end
|
393
|
+
|
190
394
|
def boot_options
|
191
|
-
|
395
|
+
# Return array of OpenStructs for boot options
|
396
|
+
options = @idrac_client.boot_options
|
397
|
+
options.map { |opt| OpenStruct.new(opt) }
|
192
398
|
end
|
193
399
|
|
194
|
-
def set_boot_override(target,
|
195
|
-
@idrac_client.set_boot_override(target,
|
400
|
+
def set_boot_override(target, enabled: "Once", mode: nil)
|
401
|
+
@idrac_client.set_boot_override(target, enabled: enabled, mode: mode)
|
196
402
|
end
|
197
403
|
|
198
404
|
def clear_boot_override
|
@@ -207,24 +413,45 @@ module Radfish
|
|
207
413
|
@idrac_client.get_boot_devices
|
208
414
|
end
|
209
415
|
|
210
|
-
def boot_to_pxe
|
211
|
-
@idrac_client.boot_to_pxe
|
416
|
+
def boot_to_pxe(enabled: "Once", mode: nil)
|
417
|
+
@idrac_client.boot_to_pxe(enabled: enabled, mode: mode)
|
418
|
+
end
|
419
|
+
|
420
|
+
def boot_to_disk(enabled: "Once", mode: nil)
|
421
|
+
@idrac_client.boot_to_disk(enabled: enabled, mode: mode)
|
422
|
+
end
|
423
|
+
|
424
|
+
def boot_to_cd(enabled: "Once", mode: nil)
|
425
|
+
@idrac_client.boot_to_cd(enabled: enabled, mode: mode)
|
212
426
|
end
|
213
427
|
|
214
|
-
def
|
215
|
-
@idrac_client.
|
428
|
+
def boot_to_usb(enabled: "Once", mode: nil)
|
429
|
+
@idrac_client.boot_to_usb(enabled: enabled, mode: mode)
|
216
430
|
end
|
217
431
|
|
218
|
-
def
|
219
|
-
@idrac_client.
|
432
|
+
def boot_to_bios_setup(enabled: "Once", mode: nil)
|
433
|
+
@idrac_client.boot_to_bios_setup(enabled: enabled, mode: mode)
|
220
434
|
end
|
221
435
|
|
222
|
-
|
223
|
-
|
436
|
+
# PCI Devices
|
437
|
+
|
438
|
+
def pci_devices
|
439
|
+
devices = @idrac_client.pci_devices
|
440
|
+
return [] unless devices
|
441
|
+
|
442
|
+
# Convert to OpenStruct for dot notation access
|
443
|
+
devices.map { |device| OpenStruct.new(device) }
|
224
444
|
end
|
225
445
|
|
226
|
-
def
|
227
|
-
@idrac_client.
|
446
|
+
def nics_with_pci_info
|
447
|
+
nics = @idrac_client.nics
|
448
|
+
pci = pci_devices
|
449
|
+
|
450
|
+
# Use the existing nics_to_pci method from idrac gem
|
451
|
+
nics_with_pci = @idrac_client.nics_to_pci(nics, pci.map(&:to_h))
|
452
|
+
|
453
|
+
# Convert to OpenStruct
|
454
|
+
nics_with_pci.map { |nic| OpenStruct.new(nic) }
|
228
455
|
end
|
229
456
|
|
230
457
|
# Jobs
|
@@ -245,14 +472,112 @@ module Radfish
|
|
245
472
|
@idrac_client.cancel_job(job_id)
|
246
473
|
end
|
247
474
|
|
248
|
-
def
|
249
|
-
@idrac_client.clear_jobs
|
475
|
+
def clear_jobs!
|
476
|
+
@idrac_client.clear_jobs!
|
250
477
|
end
|
251
478
|
|
252
479
|
def jobs_summary
|
253
480
|
jobs
|
254
481
|
end
|
255
482
|
|
483
|
+
# BMC Management
|
484
|
+
|
485
|
+
def ensure_vendor_specific_bmc_ready!
|
486
|
+
# For iDRAC, ensure the Lifecycle Controller is enabled
|
487
|
+
@idrac_client.ensure_lifecycle_controller!
|
488
|
+
end
|
489
|
+
|
490
|
+
# BIOS Configuration
|
491
|
+
|
492
|
+
def bios_error_prompt_disabled?
|
493
|
+
@idrac_client.bios_error_prompt_disabled?
|
494
|
+
end
|
495
|
+
|
496
|
+
def bios_hdd_placeholder_enabled?
|
497
|
+
@idrac_client.bios_hdd_placeholder_enabled?
|
498
|
+
end
|
499
|
+
|
500
|
+
def bios_os_power_control_enabled?
|
501
|
+
@idrac_client.bios_os_power_control_enabled?
|
502
|
+
end
|
503
|
+
|
504
|
+
def ensure_uefi_boot
|
505
|
+
@idrac_client.ensure_uefi_boot
|
506
|
+
end
|
507
|
+
|
508
|
+
def set_one_time_boot_to_virtual_media
|
509
|
+
# Use iDRAC's existing method for setting one-time boot to virtual media
|
510
|
+
@idrac_client.set_one_time_virtual_media_boot
|
511
|
+
end
|
512
|
+
|
513
|
+
def set_boot_order_hd_first
|
514
|
+
# Use iDRAC's existing method for setting boot order to HD first
|
515
|
+
@idrac_client.set_boot_order_hd_first
|
516
|
+
end
|
517
|
+
|
518
|
+
def ensure_sensible_bios!(options = {})
|
519
|
+
# Check current state
|
520
|
+
if bios_error_prompt_disabled? &&
|
521
|
+
bios_hdd_placeholder_enabled? &&
|
522
|
+
bios_os_power_control_enabled?
|
523
|
+
puts "BIOS settings already configured correctly".green
|
524
|
+
return { changes_made: false }
|
525
|
+
end
|
526
|
+
|
527
|
+
puts "Configuring BIOS settings...".yellow
|
528
|
+
|
529
|
+
# Build the System Configuration Profile (SCP)
|
530
|
+
scp = {}
|
531
|
+
|
532
|
+
# Disable error prompt (don't halt on errors)
|
533
|
+
if !bios_error_prompt_disabled?
|
534
|
+
scp = @idrac_client.merge_scp(scp, {
|
535
|
+
"BIOS.Setup.1-1" => {
|
536
|
+
"ErrPrompt" => "Disabled"
|
537
|
+
}
|
538
|
+
})
|
539
|
+
end
|
540
|
+
|
541
|
+
# Enable HDD placeholder for boot order control
|
542
|
+
if !bios_hdd_placeholder_enabled?
|
543
|
+
scp = @idrac_client.merge_scp(scp, {
|
544
|
+
"BIOS.Setup.1-1" => {
|
545
|
+
"HddPlaceholder" => "Enabled"
|
546
|
+
}
|
547
|
+
})
|
548
|
+
end
|
549
|
+
|
550
|
+
# Enable OS power control
|
551
|
+
if !bios_os_power_control_enabled?
|
552
|
+
scp = @idrac_client.merge_scp(scp, {
|
553
|
+
"BIOS.Setup.1-1" => {
|
554
|
+
"ProcCStates" => "Enabled",
|
555
|
+
"SysProfile" => "PerfPerWattOptimizedOs",
|
556
|
+
"ProcPwrPerf" => "OsDbpm"
|
557
|
+
}
|
558
|
+
})
|
559
|
+
end
|
560
|
+
|
561
|
+
# Set UEFI boot mode
|
562
|
+
scp = @idrac_client.merge_scp(scp, {
|
563
|
+
"BIOS.Setup.1-1" => {
|
564
|
+
"BootMode" => "Uefi"
|
565
|
+
}
|
566
|
+
})
|
567
|
+
|
568
|
+
# Disable host header check for better compatibility
|
569
|
+
scp = @idrac_client.merge_scp(scp, {
|
570
|
+
"iDRAC.Embedded.1" => {
|
571
|
+
"WebServer.1#HostHeaderCheck" => "Disabled"
|
572
|
+
}
|
573
|
+
})
|
574
|
+
|
575
|
+
# Apply the configuration
|
576
|
+
@idrac_client.set_system_configuration_profile(scp)
|
577
|
+
|
578
|
+
{ changes_made: true }
|
579
|
+
end
|
580
|
+
|
256
581
|
# Utility
|
257
582
|
|
258
583
|
def sel_log
|
@@ -295,18 +620,74 @@ module Radfish
|
|
295
620
|
@idrac_client.get_firmware_version
|
296
621
|
end
|
297
622
|
|
623
|
+
def bmc_info
|
624
|
+
# Map iDRAC gem data to radfish format
|
625
|
+
info = {}
|
626
|
+
|
627
|
+
# Get firmware version from idrac gem
|
628
|
+
info[:firmware_version] = @idrac_client.get_firmware_version
|
629
|
+
|
630
|
+
# Get iDRAC generation (7/8/9) from idrac gem's license_version method
|
631
|
+
info[:license_version] = @idrac_client.license_version&.to_s
|
632
|
+
|
633
|
+
# Get Redfish version from idrac gem
|
634
|
+
info[:redfish_version] = @idrac_client.redfish_version
|
635
|
+
|
636
|
+
# Get network info for MAC and IP
|
637
|
+
network = @idrac_client.get_bmc_network
|
638
|
+
if network.is_a?(Hash)
|
639
|
+
info[:mac_address] = network["mac"]
|
640
|
+
info[:ip_address] = network["ipv4"]
|
641
|
+
info[:hostname] = network["hostname"] || network["fqdn"]
|
642
|
+
end
|
643
|
+
|
644
|
+
# Get health status from system info
|
645
|
+
system = @idrac_client.system_info
|
646
|
+
if system.is_a?(Hash)
|
647
|
+
info[:health] = system.dig("Status", "Health") || system.dig("Status", "HealthRollup")
|
648
|
+
end
|
649
|
+
|
650
|
+
info
|
651
|
+
end
|
652
|
+
|
653
|
+
def system_health
|
654
|
+
# Convert hash to OpenStruct for dot notation access
|
655
|
+
health_data = @idrac_client.system_health
|
656
|
+
OpenStruct.new(health_data)
|
657
|
+
end
|
658
|
+
|
298
659
|
# Additional iDRAC-specific methods
|
299
660
|
|
300
661
|
def screenshot
|
301
|
-
@idrac_client.screenshot
|
662
|
+
@idrac_client.screenshot
|
302
663
|
end
|
303
664
|
|
304
|
-
def
|
305
|
-
@idrac_client.
|
665
|
+
def license_info
|
666
|
+
@idrac_client.license_info
|
306
667
|
end
|
307
668
|
|
308
|
-
|
309
|
-
|
669
|
+
# Network management
|
670
|
+
|
671
|
+
def get_bmc_network
|
672
|
+
@idrac_client.get_bmc_network
|
673
|
+
end
|
674
|
+
|
675
|
+
def set_bmc_network(ipv4: nil, mask: nil, gateway: nil,
|
676
|
+
dns_primary: nil, dns_secondary: nil, hostname: nil,
|
677
|
+
dhcp: false)
|
678
|
+
@idrac_client.set_bmc_network(
|
679
|
+
ipv4: ipv4,
|
680
|
+
mask: mask,
|
681
|
+
gateway: gateway,
|
682
|
+
dns_primary: dns_primary,
|
683
|
+
dns_secondary: dns_secondary,
|
684
|
+
hostname: hostname,
|
685
|
+
dhcp: dhcp
|
686
|
+
)
|
687
|
+
end
|
688
|
+
|
689
|
+
def set_bmc_dhcp
|
690
|
+
@idrac_client.set_bmc_dhcp
|
310
691
|
end
|
311
692
|
end
|
312
693
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: radfish-idrac
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Siegel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-09-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: radfish
|
@@ -85,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '0'
|
87
87
|
requirements: []
|
88
|
-
rubygems_version: 3.
|
88
|
+
rubygems_version: 3.5.22
|
89
89
|
signing_key:
|
90
90
|
specification_version: 4
|
91
91
|
summary: Dell iDRAC adapter for Radfish
|