idrac 0.1.31 → 0.1.38
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/README.md +48 -101
- data/bin/idrac +128 -12
- data/idrac.gemspec +9 -8
- data/lib/idrac/version.rb +1 -1
- data/lib/idrac.rb +1 -0
- metadata +3 -36
- data/.rspec +0 -3
- data/Rakefile +0 -17
- data/dell_firmware_downloads/Catalog.etag +0 -1
- data/dell_firmware_downloads/Catalog.xml +0 -0
- data/idrac-0.1.6/.rspec +0 -3
- data/idrac-0.1.6/README.md +0 -103
- data/idrac-0.1.6/Rakefile +0 -17
- data/idrac-0.1.6/bin/console +0 -11
- data/idrac-0.1.6/bin/idrac +0 -179
- data/idrac-0.1.6/bin/setup +0 -8
- data/idrac-0.1.6/idrac.gemspec +0 -51
- data/idrac-0.1.6/lib/idrac/client.rb +0 -109
- data/idrac-0.1.6/lib/idrac/firmware.rb +0 -366
- data/idrac-0.1.6/lib/idrac/version.rb +0 -5
- data/idrac-0.1.6/lib/idrac.rb +0 -30
- data/idrac-0.1.6/sig/idrac.rbs +0 -4
- data/idrac-0.1.7/.rspec +0 -3
- data/idrac-0.1.7/README.md +0 -103
- data/idrac-0.1.7/Rakefile +0 -17
- data/idrac-0.1.7/bin/console +0 -11
- data/idrac-0.1.7/bin/idrac +0 -179
- data/idrac-0.1.7/bin/setup +0 -8
- data/idrac-0.1.7/idrac.gemspec +0 -51
- data/idrac-0.1.7/lib/idrac/client.rb +0 -109
- data/idrac-0.1.7/lib/idrac/firmware.rb +0 -366
- data/idrac-0.1.7/lib/idrac/screenshot.rb +0 -49
- data/idrac-0.1.7/lib/idrac/version.rb +0 -5
- data/idrac-0.1.7/lib/idrac.rb +0 -30
- data/idrac-0.1.7/sig/idrac.rbs +0 -4
- data/idrac.py +0 -500
- data/sig/idrac.rbs +0 -4
- data/test_firmware_update.rb +0 -68
- data/updater.rb +0 -729
data/idrac-0.1.6/Rakefile
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "bundler/gem_tasks"
|
4
|
-
require "rspec/core/rake_task"
|
5
|
-
|
6
|
-
RSpec::Core::RakeTask.new(:spec)
|
7
|
-
|
8
|
-
task default: :spec
|
9
|
-
|
10
|
-
# Add a task that tags and pushes to the repository and builds
|
11
|
-
# the gem and pushes it to rubygems.org.
|
12
|
-
# Depend on the build task to ensure the gem is up to date.
|
13
|
-
task :release => [:build] do
|
14
|
-
system "git tag v#{Idrac::VERSION}"
|
15
|
-
system "git push --tags"
|
16
|
-
system "gem push pkg/idrac-#{Idrac::VERSION}.gem"
|
17
|
-
end
|
data/idrac-0.1.6/bin/console
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "bundler/setup"
|
5
|
-
require "idrac"
|
6
|
-
|
7
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
-
# with your gem easier. You can also use a different console, if you like.
|
9
|
-
|
10
|
-
require "irb"
|
11
|
-
IRB.start(__FILE__)
|
data/idrac-0.1.6/bin/idrac
DELETED
@@ -1,179 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# Attempt to load bundler/setup, but don't fail if it's not available
|
4
|
-
begin
|
5
|
-
require "bundler/setup"
|
6
|
-
rescue LoadError
|
7
|
-
# Continue without bundler
|
8
|
-
end
|
9
|
-
|
10
|
-
# Load required gems directly
|
11
|
-
require "thor"
|
12
|
-
require "idrac"
|
13
|
-
|
14
|
-
module IDRAC
|
15
|
-
class CLI < Thor
|
16
|
-
class_option :host, type: :string, required: true, desc: "iDRAC host address"
|
17
|
-
class_option :username, type: :string, required: true, desc: "iDRAC username"
|
18
|
-
class_option :password, type: :string, required: true, desc: "iDRAC password"
|
19
|
-
class_option :port, type: :numeric, default: 443, desc: "iDRAC port"
|
20
|
-
class_option :no_ssl, type: :boolean, default: false, desc: "Disable SSL"
|
21
|
-
class_option :no_verify_ssl, type: :boolean, default: false, desc: "Disable SSL verification"
|
22
|
-
|
23
|
-
desc "firmware:update PATH", "Update firmware using the specified file"
|
24
|
-
method_option :wait, type: :boolean, default: true, desc: "Wait for the update to complete"
|
25
|
-
method_option :timeout, type: :numeric, default: 3600, desc: "Timeout in seconds when waiting"
|
26
|
-
def firmware_update(path)
|
27
|
-
client = create_client
|
28
|
-
firmware = IDRAC::Firmware.new(client)
|
29
|
-
|
30
|
-
begin
|
31
|
-
job_id = firmware.update(path, wait: options[:wait], timeout: options[:timeout])
|
32
|
-
puts "Firmware update initiated with job ID: #{job_id}"
|
33
|
-
rescue IDRAC::Error => e
|
34
|
-
puts "Error: #{e.message}"
|
35
|
-
exit 1
|
36
|
-
ensure
|
37
|
-
client.logout
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
desc "firmware:catalog [DIRECTORY]", "Download Dell firmware catalog"
|
42
|
-
def firmware_catalog(directory = nil)
|
43
|
-
client = create_client
|
44
|
-
firmware = IDRAC::Firmware.new(client)
|
45
|
-
|
46
|
-
begin
|
47
|
-
catalog_path = firmware.download_catalog(directory)
|
48
|
-
puts "Catalog downloaded to: #{catalog_path}"
|
49
|
-
rescue IDRAC::Error => e
|
50
|
-
puts "Error: #{e.message}"
|
51
|
-
exit 1
|
52
|
-
ensure
|
53
|
-
client.logout
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
desc "firmware:status", "Show current firmware status and available updates"
|
58
|
-
method_option :catalog, type: :string, desc: "Path to existing catalog file"
|
59
|
-
def firmware_status
|
60
|
-
client = create_client
|
61
|
-
firmware = IDRAC::Firmware.new(client)
|
62
|
-
|
63
|
-
begin
|
64
|
-
# Get system inventory
|
65
|
-
inventory = firmware.get_system_inventory
|
66
|
-
|
67
|
-
puts "System Information:"
|
68
|
-
puts " Model: #{inventory[:system][:model]}"
|
69
|
-
puts " Manufacturer: #{inventory[:system][:manufacturer]}"
|
70
|
-
puts " Service Tag: #{inventory[:system][:service_tag]}"
|
71
|
-
puts " BIOS Version: #{inventory[:system][:bios_version]}"
|
72
|
-
|
73
|
-
puts "\nInstalled Firmware:"
|
74
|
-
inventory[:firmware].each do |fw|
|
75
|
-
puts " #{fw[:name]}: #{fw[:version]} (#{fw[:updateable] ? 'Updateable' : 'Not Updateable'})"
|
76
|
-
end
|
77
|
-
|
78
|
-
# Check for updates if catalog is available
|
79
|
-
if options[:catalog] || File.exist?(File.join(Dir.pwd, "Catalog.xml"))
|
80
|
-
catalog_path = options[:catalog] || File.join(Dir.pwd, "Catalog.xml")
|
81
|
-
puts "\nChecking for updates using catalog: #{catalog_path}"
|
82
|
-
|
83
|
-
updates = firmware.check_updates(catalog_path)
|
84
|
-
|
85
|
-
if updates.empty?
|
86
|
-
puts "No updates available."
|
87
|
-
else
|
88
|
-
puts "\nAvailable Updates:"
|
89
|
-
updates.each do |update|
|
90
|
-
puts " #{update[:name]}: #{update[:current_version]} -> #{update[:available_version]}"
|
91
|
-
end
|
92
|
-
end
|
93
|
-
else
|
94
|
-
puts "\nTo check for updates, download the catalog first with 'idrac firmware:catalog'"
|
95
|
-
end
|
96
|
-
rescue IDRAC::Error => e
|
97
|
-
puts "Error: #{e.message}"
|
98
|
-
exit 1
|
99
|
-
ensure
|
100
|
-
client.logout
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
desc "firmware:interactive", "Interactive firmware update"
|
105
|
-
method_option :catalog, type: :string, desc: "Path to existing catalog file"
|
106
|
-
def firmware_interactive
|
107
|
-
client = create_client
|
108
|
-
firmware = IDRAC::Firmware.new(client)
|
109
|
-
|
110
|
-
begin
|
111
|
-
catalog_path = options[:catalog]
|
112
|
-
|
113
|
-
# If no catalog specified, check if one exists in current directory
|
114
|
-
if catalog_path.nil? && File.exist?(File.join(Dir.pwd, "Catalog.xml"))
|
115
|
-
catalog_path = File.join(Dir.pwd, "Catalog.xml")
|
116
|
-
end
|
117
|
-
|
118
|
-
# If still no catalog, download it
|
119
|
-
if catalog_path.nil?
|
120
|
-
puts "No catalog found. Downloading..."
|
121
|
-
catalog_path = firmware.download_catalog
|
122
|
-
end
|
123
|
-
|
124
|
-
firmware.interactive_update(catalog_path)
|
125
|
-
rescue IDRAC::Error => e
|
126
|
-
puts "Error: #{e.message}"
|
127
|
-
exit 1
|
128
|
-
ensure
|
129
|
-
client.logout
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
desc "screenshot", "Take a screenshot of the current iDRAC console"
|
134
|
-
method_option :output, type: :string, desc: "Output filename (default: idrac_screenshot_timestamp.png)"
|
135
|
-
def screenshot
|
136
|
-
client = create_client
|
137
|
-
|
138
|
-
begin
|
139
|
-
# Create a Screenshot instance directly
|
140
|
-
screenshot = IDRAC::Screenshot.new(client)
|
141
|
-
filename = screenshot.capture
|
142
|
-
|
143
|
-
# Rename the file if output option is provided
|
144
|
-
if options[:output]
|
145
|
-
new_filename = options[:output]
|
146
|
-
File.rename(filename, new_filename)
|
147
|
-
filename = new_filename
|
148
|
-
end
|
149
|
-
|
150
|
-
puts "Screenshot saved to: #{filename}"
|
151
|
-
rescue IDRAC::Error => e
|
152
|
-
puts "Error: #{e.message}"
|
153
|
-
exit 1
|
154
|
-
ensure
|
155
|
-
client.logout
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
map "firmware:update" => :firmware_update
|
160
|
-
map "firmware:catalog" => :firmware_catalog
|
161
|
-
map "firmware:status" => :firmware_status
|
162
|
-
map "firmware:interactive" => :firmware_interactive
|
163
|
-
|
164
|
-
private
|
165
|
-
|
166
|
-
def create_client
|
167
|
-
IDRAC::Client.new(
|
168
|
-
host: options[:host],
|
169
|
-
username: options[:username],
|
170
|
-
password: options[:password],
|
171
|
-
port: options[:port],
|
172
|
-
use_ssl: !options[:no_ssl],
|
173
|
-
verify_ssl: !options[:no_verify_ssl]
|
174
|
-
)
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
IDRAC::CLI.start(ARGV)
|
data/idrac-0.1.6/bin/setup
DELETED
data/idrac-0.1.6/idrac.gemspec
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "lib/idrac/version"
|
4
|
-
|
5
|
-
Gem::Specification.new do |spec|
|
6
|
-
spec.name = "idrac"
|
7
|
-
spec.version = IDRAC::VERSION
|
8
|
-
spec.authors = ["Jonathan Siegel"]
|
9
|
-
spec.email = ["<248302+usiegj00@users.noreply.github.com>"]
|
10
|
-
|
11
|
-
spec.summary = "API Client for Dell iDRAC"
|
12
|
-
spec.description = "A Ruby client for the Dell iDRAC API"
|
13
|
-
spec.homepage = "http://github.com"
|
14
|
-
spec.license = "MIT"
|
15
|
-
spec.required_ruby_version = ">= 3.2.0" # Updated to support Ruby 3.2.x
|
16
|
-
|
17
|
-
# spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
|
18
|
-
|
19
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
20
|
-
# spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
|
21
|
-
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
22
|
-
|
23
|
-
# Specify which files should be added to the gem when it is released.
|
24
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
-
spec.files = Dir.chdir(__dir__) do
|
26
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
27
|
-
(File.expand_path(f) == __FILE__) ||
|
28
|
-
f.start_with?(*%w[test/ spec/ features/ .git .circleci appveyor Gemfile])
|
29
|
-
end
|
30
|
-
end
|
31
|
-
spec.bindir = "bin"
|
32
|
-
spec.executables = ["idrac"]
|
33
|
-
spec.require_paths = ["lib"]
|
34
|
-
|
35
|
-
# Dependencies - Using more flexible version constraints
|
36
|
-
spec.add_dependency "httparty", ">= 0.21.0", "< 0.22.0"
|
37
|
-
spec.add_dependency "nokogiri", ">= 1.15.0", "< 1.19.0"
|
38
|
-
spec.add_dependency "faraday", ">= 2.7.0", "< 2.8.0"
|
39
|
-
spec.add_dependency "faraday-multipart", ">= 1.0.0", "< 1.1.0"
|
40
|
-
spec.add_dependency "thor", ">= 1.2.0", "< 1.4.0"
|
41
|
-
spec.add_dependency "base64", "~> 0.1", ">= 0.1.0"
|
42
|
-
|
43
|
-
# Development dependencies
|
44
|
-
spec.add_development_dependency "bundler", "~> 2.4", ">= 2.4.0"
|
45
|
-
spec.add_development_dependency "rake", "~> 13.0"
|
46
|
-
spec.add_development_dependency "rspec", "~> 3.12"
|
47
|
-
spec.add_development_dependency "debug", "~> 1.8"
|
48
|
-
|
49
|
-
# For more information and examples about making a new gem, check out our
|
50
|
-
# guide at: https://bundler.io/guides/creating_gem.html
|
51
|
-
end
|
@@ -1,109 +0,0 @@
|
|
1
|
-
require 'faraday'
|
2
|
-
require 'faraday/multipart'
|
3
|
-
require 'nokogiri'
|
4
|
-
require 'base64'
|
5
|
-
require 'uri'
|
6
|
-
require 'httparty'
|
7
|
-
|
8
|
-
module IDRAC
|
9
|
-
class Client
|
10
|
-
attr_reader :host, :username, :password, :port, :use_ssl, :verify_ssl
|
11
|
-
|
12
|
-
def initialize(host:, username:, password:, port: 443, use_ssl: true, verify_ssl: true)
|
13
|
-
@host = host
|
14
|
-
@username = username
|
15
|
-
@password = password
|
16
|
-
@port = port
|
17
|
-
@use_ssl = use_ssl
|
18
|
-
@verify_ssl = verify_ssl
|
19
|
-
@session_id = nil
|
20
|
-
@cookies = nil
|
21
|
-
end
|
22
|
-
|
23
|
-
def connection
|
24
|
-
@connection ||= Faraday.new(url: base_url, ssl: { verify: verify_ssl }) do |faraday|
|
25
|
-
faraday.request :multipart
|
26
|
-
faraday.request :url_encoded
|
27
|
-
faraday.adapter Faraday.default_adapter
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def login
|
32
|
-
response = connection.post('/data/login') do |req|
|
33
|
-
req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
34
|
-
req.body = "user=#{username}&password=#{password}"
|
35
|
-
end
|
36
|
-
|
37
|
-
if response.status == 200
|
38
|
-
# Extract session ID from response
|
39
|
-
doc = Nokogiri::HTML(response.body)
|
40
|
-
@session_id = doc.at_css('script:contains("_this.SID")').text.match(/_this\.SID\s*=\s*"([^"]+)"/)[1] rescue nil
|
41
|
-
|
42
|
-
# Store cookies for screenshot functionality
|
43
|
-
@cookies = response.headers['set-cookie']
|
44
|
-
|
45
|
-
# Extract forward URL for screenshot functionality
|
46
|
-
xml_doc = Nokogiri::XML(response.body)
|
47
|
-
error_message = xml_doc.at_xpath('//errorMsg')&.text
|
48
|
-
|
49
|
-
if error_message && !error_message.empty?
|
50
|
-
raise Error, "Error Message: #{error_message}"
|
51
|
-
end
|
52
|
-
|
53
|
-
forward_url = xml_doc.xpath('//forwardUrl').text
|
54
|
-
return forward_url
|
55
|
-
else
|
56
|
-
raise Error, "Login failed with status #{response.status}: #{response.body}"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def logout
|
61
|
-
return unless @session_id
|
62
|
-
|
63
|
-
response = connection.get('/data/logout') do |req|
|
64
|
-
req.headers['Cookie'] = "sessionid=#{@session_id}"
|
65
|
-
end
|
66
|
-
|
67
|
-
@session_id = nil
|
68
|
-
@cookies = nil
|
69
|
-
response.status == 200
|
70
|
-
end
|
71
|
-
|
72
|
-
def authenticated_request(method, path, options = {})
|
73
|
-
login unless @session_id
|
74
|
-
|
75
|
-
options[:headers] ||= {}
|
76
|
-
options[:headers]['Cookie'] = "sessionid=#{@session_id}"
|
77
|
-
|
78
|
-
response = connection.send(method, path, options[:params]) do |req|
|
79
|
-
req.headers.merge!(options[:headers])
|
80
|
-
req.body = options[:body] if options[:body]
|
81
|
-
end
|
82
|
-
|
83
|
-
response
|
84
|
-
end
|
85
|
-
|
86
|
-
def get(path:, headers: {})
|
87
|
-
response = HTTParty.get(
|
88
|
-
"#{base_url}/#{path}",
|
89
|
-
headers: {
|
90
|
-
"User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
|
91
|
-
"Accept-Encoding" => "deflate, gzip",
|
92
|
-
"Cookie" => @cookies
|
93
|
-
}.merge(headers),
|
94
|
-
verify: false
|
95
|
-
)
|
96
|
-
end
|
97
|
-
|
98
|
-
def screenshot
|
99
|
-
# Create a Screenshot instance and capture a screenshot
|
100
|
-
screenshot_instance = Screenshot.new(self)
|
101
|
-
screenshot_instance.capture
|
102
|
-
end
|
103
|
-
|
104
|
-
def base_url
|
105
|
-
protocol = use_ssl ? 'https' : 'http'
|
106
|
-
"#{protocol}://#{host}:#{port}"
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|