radfish 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8324b8cbc6f0ee5f47d551325ad7231c967e2b5ac4e77afd29377f6b2bc8127a
4
+ data.tar.gz: b394714edbd0f4cf7c888cdb2d93da4e33d4bceb1e375be1666d6ff0e7b7438d
5
+ SHA512:
6
+ metadata.gz: dce68259152ba35bfe749ca300fbeca2cc8acfd77e20fd0e0b7fa598dd43420b3c2a858b9ec2de99108822e559ec306b16c33cf4bd3977ca344e808d531b2a42
7
+ data.tar.gz: 1869fa92e7be91f7691fb4a7ab241f5206d5fdf040b8c916c105784cf725d497781a662e375ac7934bc1641fd1d60c6dd4edc4af53c263f32981aa1e94e1bed8
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Jonathan Siegel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,531 @@
1
+ # Radfish - Unified Redfish Client
2
+
3
+ A Ruby client library that provides a unified interface for managing servers via Redfish API, with automatic vendor detection and adaptation.
4
+
5
+ ## Architecture
6
+
7
+ Radfish provides a vendor-agnostic interface for server management through Redfish, automatically detecting and adapting to different hardware vendors. The architecture consists of:
8
+
9
+ ```
10
+ radfish (core gem)
11
+ ├── Core modules (define interfaces)
12
+ ├── Vendor detection
13
+ ├── Client (delegates to adapters)
14
+ ├── Base classes
15
+ └── Built-in adapters:
16
+ ├── radfish-idrac (Dell adapter)
17
+ │ └── IdracAdapter → wraps idrac gem
18
+ └── radfish-supermicro (Supermicro adapter)
19
+ └── SupermicroAdapter → wraps supermicro gem
20
+
21
+ Future adapters:
22
+ - radfish-hpe (HPE iLO)
23
+ - radfish-lenovo (Lenovo XCC)
24
+ - radfish-asrockrack
25
+ ```
26
+
27
+ ## Features
28
+
29
+ ### Automatic Vendor Detection
30
+ - Automatically identifies Dell, Supermicro, HPE, Lenovo, and ASRockRack servers
31
+ - Falls back to generic Redfish if vendor cannot be determined
32
+ - Can be overridden with explicit vendor specification
33
+
34
+ ### Unified Interface
35
+ Regardless of vendor, all adapters provide:
36
+
37
+ - **Power Management**: on/off/restart/cycle
38
+ - **System Inventory**: CPUs, memory, NICs, storage
39
+ - **Virtual Media**: Mount/unmount ISOs
40
+ - **Boot Configuration**: Boot order, one-time boot
41
+ - **Monitoring**: Temperatures, fans, power consumption
42
+ - **Event Logs**: System event log management
43
+ - **Jobs/Tasks**: Long-running operation monitoring
44
+
45
+ ### Vendor-Specific Features
46
+ Adapters can expose vendor-specific functionality while maintaining the common interface.
47
+
48
+ ## Installation
49
+
50
+ Add to your Gemfile:
51
+
52
+ ```ruby
53
+ gem 'radfish'
54
+ ```
55
+
56
+ Or install directly:
57
+
58
+ ```bash
59
+ gem install radfish
60
+ ```
61
+
62
+ The radfish gem now includes built-in support for:
63
+ - **Dell iDRAC** (via radfish-idrac)
64
+ - **Supermicro** (via radfish-supermicro)
65
+
66
+ These common adapters are included automatically, so you don't need to install them separately. Additional vendor support can be added as needed.
67
+
68
+ ## CLI Usage
69
+
70
+ Radfish includes a powerful command-line interface for server management:
71
+
72
+ ### Quick Start
73
+
74
+ ```bash
75
+ # Check system status
76
+ radfish system --host 192.168.1.100 -u admin -p password
77
+
78
+ # Power operations
79
+ radfish power status --host 192.168.1.100 -u admin -p password
80
+ radfish power on --host 192.168.1.100 -u admin -p password
81
+ radfish power restart --host 192.168.1.100 -u admin -p password
82
+
83
+ # Virtual media operations
84
+ radfish media status --host 192.168.1.100 -u admin -p password
85
+ radfish media mount https://example.com/ubuntu.iso --host 192.168.1.100 -u admin -p password
86
+ radfish media unmount --host 192.168.1.100 -u admin -p password
87
+
88
+ # Boot configuration
89
+ radfish boot status --host 192.168.1.100 -u admin -p password
90
+ radfish boot cd --once --host 192.168.1.100 -u admin -p password
91
+ radfish boot pxe --uefi --host 192.168.1.100 -u admin -p password
92
+ ```
93
+
94
+ ### Environment Variables
95
+
96
+ Configure common settings via environment variables to avoid repetition:
97
+
98
+ ```bash
99
+ export RADFISH_HOST=192.168.1.100
100
+ export RADFISH_USERNAME=admin
101
+ export RADFISH_PASSWORD=password
102
+ export RADFISH_VENDOR=supermicro # Optional: auto-detects if not set
103
+ export RADFISH_PORT=443 # Optional: defaults to 443
104
+
105
+ # Now commands are simpler
106
+ radfish system
107
+ radfish power on
108
+ radfish media mount https://example.com/ubuntu.iso
109
+ ```
110
+
111
+ ### Available Commands
112
+
113
+ #### System Information
114
+ ```bash
115
+ radfish system [OPTIONS] # Display system information
116
+ radfish cpus [OPTIONS] # List CPUs
117
+ radfish memory [OPTIONS] # List memory modules
118
+ radfish nics [OPTIONS] # List network interfaces
119
+ radfish drives [OPTIONS] # List storage drives
120
+ radfish psus [OPTIONS] # List power supplies
121
+ ```
122
+
123
+ #### Power Management
124
+ ```bash
125
+ radfish power status [OPTIONS] # Show current power state
126
+ radfish power on [OPTIONS] # Power on the system
127
+ radfish power off [OPTIONS] # Power off the system
128
+ radfish power restart [OPTIONS] # Restart the system
129
+ radfish power cycle [OPTIONS] # Power cycle the system
130
+ ```
131
+
132
+ #### Virtual Media
133
+ ```bash
134
+ radfish media status [OPTIONS] # Show virtual media status
135
+ radfish media mount URL [OPTIONS] # Mount ISO from URL
136
+ radfish media unmount [OPTIONS] # Unmount all virtual media
137
+ ```
138
+
139
+ #### Boot Configuration
140
+ ```bash
141
+ radfish boot status [OPTIONS] # Show boot configuration
142
+ radfish boot cd [OPTIONS] # Boot from virtual CD
143
+ radfish boot pxe [OPTIONS] # Boot from network (PXE)
144
+ radfish boot disk [OPTIONS] # Boot from hard disk
145
+ radfish boot bios [OPTIONS] # Boot to BIOS setup
146
+
147
+ # Boot options:
148
+ --once # Set boot override for next boot only
149
+ --continuous # Set boot override until manually cleared
150
+ --uefi # Use UEFI boot mode
151
+ --legacy # Use Legacy/BIOS boot mode
152
+ ```
153
+
154
+ #### Monitoring
155
+ ```bash
156
+ radfish fans [OPTIONS] # Show fan speeds
157
+ radfish temps [OPTIONS] # Show temperatures
158
+ radfish power-consumption [OPTIONS] # Show power consumption
159
+ radfish sel [OPTIONS] # Show system event log
160
+ radfish clear-sel [OPTIONS] # Clear system event log
161
+ ```
162
+
163
+ ### Global Options
164
+
165
+ All commands support these options:
166
+
167
+ ```bash
168
+ --host, -h HOST # BMC hostname or IP address
169
+ --username, -u USER # BMC username
170
+ --password, -p PASS # BMC password
171
+ --vendor VENDOR # Force specific vendor (dell, supermicro, etc.)
172
+ --port PORT # BMC port (default: 443)
173
+ --json # Output in JSON format
174
+ --verbose, -v # Enable verbose output (repeat for more verbosity)
175
+ --no-verify-ssl # Skip SSL certificate verification
176
+ ```
177
+
178
+ ### Output Formats
179
+
180
+ #### Default (Human-Readable)
181
+ ```bash
182
+ $ radfish system
183
+ System Information:
184
+ Manufacturer: Supermicro
185
+ Model: X11SCL-F
186
+ Serial: 0123456789
187
+ Power State: On
188
+ Health: OK
189
+ ```
190
+
191
+ #### JSON Format
192
+ ```bash
193
+ $ radfish system --json
194
+ {
195
+ "manufacturer": "Supermicro",
196
+ "model": "X11SCL-F",
197
+ "serial": "0123456789",
198
+ "power_state": "On",
199
+ "health": "OK"
200
+ }
201
+ ```
202
+
203
+ ### Common Workflows
204
+
205
+ #### Mount ISO and Boot from It
206
+ ```bash
207
+ # Mount the ISO
208
+ radfish media mount https://releases.ubuntu.com/24.04/ubuntu-24.04-live-server-amd64.iso
209
+
210
+ # Configure one-time boot from CD with UEFI
211
+ radfish boot cd --once --uefi
212
+
213
+ # Restart the system
214
+ radfish power restart
215
+ ```
216
+
217
+ #### Power Cycle with Monitoring
218
+ ```bash
219
+ # Check current status
220
+ radfish power status
221
+ radfish temps
222
+
223
+ # Perform power cycle
224
+ radfish power cycle
225
+
226
+ # Monitor until back online
227
+ watch radfish power status
228
+ ```
229
+
230
+ #### Automated Script Example
231
+ ```bash
232
+ #!/bin/bash
233
+ # Provision multiple servers
234
+
235
+ SERVERS="192.168.1.100 192.168.1.101 192.168.1.102"
236
+ ISO_URL="https://example.com/os-installer.iso"
237
+
238
+ for server in $SERVERS; do
239
+ echo "Provisioning $server..."
240
+
241
+ # Mount ISO
242
+ radfish media mount $ISO_URL --host $server -u admin -p password
243
+
244
+ # Set one-time boot from CD
245
+ radfish boot cd --once --host $server -u admin -p password
246
+
247
+ # Restart
248
+ radfish power restart --host $server -u admin -p password
249
+ done
250
+ ```
251
+
252
+ ## Library Usage
253
+
254
+ ### Basic Usage with Auto-Detection
255
+
256
+ ```ruby
257
+ require 'radfish'
258
+
259
+ # Auto-detect vendor and connect
260
+ Radfish.connect(
261
+ host: '192.168.1.100',
262
+ username: 'admin',
263
+ password: 'password'
264
+ ) do |client|
265
+ puts "Connected to #{client.vendor_name} server"
266
+ puts "Power state: #{client.power_status}"
267
+
268
+ # Common operations work regardless of vendor
269
+ client.power_on
270
+ client.insert_virtual_media("http://example.com/os.iso")
271
+ client.boot_to_cd
272
+ end
273
+ ```
274
+
275
+ ### Explicit Vendor Specification
276
+
277
+ ```ruby
278
+ # Skip auto-detection if you know the vendor
279
+ client = Radfish::Client.new(
280
+ host: '192.168.1.100',
281
+ username: 'admin',
282
+ password: 'password',
283
+ vendor: 'dell' # or 'supermicro', 'hpe', etc.
284
+ )
285
+
286
+ client.login
287
+ # ... operations ...
288
+ client.logout
289
+ ```
290
+
291
+ ### Vendor Detection Only
292
+
293
+ ```ruby
294
+ # Just detect the vendor without creating a client
295
+ vendor = Radfish.detect_vendor(
296
+ host: '192.168.1.100',
297
+ username: 'admin',
298
+ password: 'password'
299
+ )
300
+ puts "Detected vendor: #{vendor}"
301
+ # => "dell", "supermicro", "hpe", etc.
302
+ ```
303
+
304
+ ### Checking Supported Features
305
+
306
+ ```ruby
307
+ client = Radfish::Client.new(
308
+ host: '192.168.1.100',
309
+ username: 'admin',
310
+ password: 'password'
311
+ )
312
+
313
+ # Check what this adapter supports
314
+ puts client.supported_features
315
+ # => [:power, :system, :storage, :virtual_media, :boot, :jobs, :utility]
316
+
317
+ # Get adapter info
318
+ puts client.info
319
+ # => {
320
+ # vendor: "supermicro",
321
+ # adapter: "Radfish::SupermicroAdapter",
322
+ # features: [:power, :system, ...],
323
+ # host: "192.168.1.100",
324
+ # base_url: "https://192.168.1.100:443"
325
+ # }
326
+ ```
327
+
328
+ ## Common Operations
329
+
330
+ ### Power Management
331
+
332
+ ```ruby
333
+ client.power_status # => "On" or "Off"
334
+ client.power_on
335
+ client.power_off
336
+ client.power_restart
337
+ client.power_cycle
338
+ ```
339
+
340
+ ### System Information
341
+
342
+ ```ruby
343
+ # Basic system info
344
+ info = client.system_info
345
+ # => { "manufacturer" => "Dell", "model" => "PowerEdge R640", ... }
346
+
347
+ # Hardware inventory
348
+ client.cpus # CPU information
349
+ client.memory # Memory DIMMs
350
+ client.nics # Network interfaces
351
+ client.drives # Physical drives
352
+ client.psus # Power supplies
353
+ ```
354
+
355
+ ### Virtual Media
356
+
357
+ ```ruby
358
+ # Check current media
359
+ media = client.virtual_media_status
360
+
361
+ # Mount an ISO
362
+ client.insert_virtual_media("http://example.com/os.iso")
363
+
364
+ # Unmount all media
365
+ client.unmount_all_media
366
+
367
+ # Mount and configure boot
368
+ client.mount_iso_and_boot("http://example.com/os.iso")
369
+ ```
370
+
371
+ ### Boot Configuration
372
+
373
+ ```ruby
374
+ # Get boot options
375
+ options = client.boot_options
376
+
377
+ # Set one-time boot
378
+ client.set_boot_override("Pxe", persistent: false)
379
+
380
+ # Quick boot methods
381
+ client.boot_to_pxe
382
+ client.boot_to_disk
383
+ client.boot_to_cd
384
+ client.boot_to_bios_setup
385
+ ```
386
+
387
+ ### Monitoring
388
+
389
+ ```ruby
390
+ # Thermal monitoring
391
+ fans = client.fans
392
+ temps = client.temperatures
393
+
394
+ # Power monitoring
395
+ power = client.power_consumption
396
+
397
+ # Event logs
398
+ events = client.sel_summary(limit: 10)
399
+ client.clear_sel_log
400
+ ```
401
+
402
+ ## Multi-Vendor Environments
403
+
404
+ Radfish shines in environments with mixed hardware vendors:
405
+
406
+ ```ruby
407
+ servers = [
408
+ { host: '192.168.1.100', vendor: 'dell' },
409
+ { host: '192.168.1.101', vendor: 'supermicro' },
410
+ { host: '192.168.1.102', vendor: nil } # auto-detect
411
+ ]
412
+
413
+ servers.each do |server_config|
414
+ Radfish.connect(
415
+ host: server_config[:host],
416
+ username: 'admin',
417
+ password: 'password',
418
+ vendor: server_config[:vendor]
419
+ ) do |client|
420
+ # Same code works for all vendors
421
+ puts "#{client.vendor_name}: #{client.power_status}"
422
+
423
+ if client.power_status == "Off"
424
+ client.power_on
425
+ end
426
+ end
427
+ end
428
+ ```
429
+
430
+ ## Configuration Options
431
+
432
+ ```ruby
433
+ Radfish::Client.new(
434
+ host: '192.168.1.100',
435
+ username: 'admin',
436
+ password: 'password',
437
+
438
+ # Optional parameters
439
+ vendor: 'dell', # Skip auto-detection
440
+ port: 443, # BMC port
441
+ use_ssl: true, # Use HTTPS
442
+ verify_ssl: false, # Verify certificates
443
+ direct_mode: false, # Use Basic Auth instead of sessions
444
+ retry_count: 3, # Retry failed requests
445
+ retry_delay: 1, # Initial delay between retries
446
+ verbosity: 0 # Debug output level (0-3)
447
+ )
448
+ ```
449
+
450
+ ## Debugging
451
+
452
+ Enable verbose output:
453
+
454
+ ```ruby
455
+ client.verbosity = 1 # Basic debug info
456
+ client.verbosity = 2 # Include request/response details
457
+ client.verbosity = 3 # Include stack traces
458
+ ```
459
+
460
+ ## Supported Vendors
461
+
462
+ Currently supported:
463
+ - **Dell** (via radfish-idrac)
464
+ - **Supermicro** (via radfish-supermicro)
465
+
466
+ Planned support:
467
+ - **HPE** (iLO)
468
+ - **Lenovo** (XCC)
469
+ - **ASRockRack**
470
+ - **Generic Redfish** (fallback)
471
+
472
+ ## Creating Custom Adapters
473
+
474
+ To add support for a new vendor, create an adapter gem:
475
+
476
+ ```ruby
477
+ # radfish-myvendor/lib/radfish/myvendor_adapter.rb
478
+ module Radfish
479
+ class MyvendorAdapter < Core::BaseClient
480
+ include Core::Power
481
+ include Core::System
482
+ # ... include other modules
483
+
484
+ def vendor
485
+ 'myvendor'
486
+ end
487
+
488
+ def power_status
489
+ # Implement vendor-specific logic
490
+ end
491
+
492
+ # ... implement required methods
493
+ end
494
+
495
+ # Register the adapter
496
+ Radfish.register_adapter('myvendor', MyvendorAdapter)
497
+ end
498
+ ```
499
+
500
+ ## Benefits of the Unified Approach
501
+
502
+ 1. **Single API**: Learn once, use everywhere
503
+ 2. **Vendor Flexibility**: Switch hardware vendors without changing code
504
+ 3. **Automatic Detection**: No need to track which vendor each server uses
505
+ 4. **Gradual Migration**: Mix vendors during hardware transitions
506
+ 5. **Simplified Testing**: Mock one interface instead of many
507
+ 6. **Future-Proof**: New vendors can be added without changing existing code
508
+
509
+ ## Migration from Direct Vendor Gems
510
+
511
+ If you're currently using the idrac or supermicro gems directly:
512
+
513
+ ```ruby
514
+ # Old way (vendor-specific)
515
+ require 'idrac'
516
+ client = IDRAC::Client.new(host: '...', ...)
517
+
518
+ # New way (unified)
519
+ require 'radfish'
520
+ require 'radfish/idrac_adapter' # or let it auto-load
521
+ client = Radfish::Client.new(host: '...', vendor: 'dell')
522
+
523
+ # Or with auto-detection
524
+ client = Radfish::Client.new(host: '...')
525
+ ```
526
+
527
+ The same method names work, so migration is straightforward.
528
+
529
+ ## License
530
+
531
+ MIT
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
7
+
8
+ desc "Run integration tests (requires real BMC)"
9
+ RSpec::Core::RakeTask.new(:integration) do |t|
10
+ t.rspec_opts = "--tag integration"
11
+ end
12
+
13
+ desc "Run all tests including integration"
14
+ task all: [:spec, :integration]
data/exe/radfish ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
5
+
6
+ require 'radfish/cli'
7
+ Radfish::CLI.start(ARGV)
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Radfish
4
+ module CLI
5
+ module Base
6
+ def self.included(base)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+ def cli_instance
12
+ @cli_instance ||= Radfish::CLI.new
13
+ end
14
+ end
15
+
16
+ def with_client(&block)
17
+ self.class.cli_instance.send(:with_client, &block)
18
+ end
19
+
20
+ def success(message)
21
+ self.class.cli_instance.send(:success, message)
22
+ end
23
+
24
+ def error(message)
25
+ self.class.cli_instance.send(:error, message)
26
+ end
27
+
28
+ def info_msg(message)
29
+ self.class.cli_instance.send(:info_msg, message)
30
+ end
31
+
32
+ def safe_call
33
+ yield
34
+ rescue => e
35
+ parent_options[:verbose] ? e.message : nil
36
+ end
37
+ end
38
+ end
39
+ end