idrac 0.1.31 → 0.1.40

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +49 -107
  3. data/bin/idrac +130 -15
  4. data/idrac.gemspec +9 -8
  5. data/lib/idrac/client.rb +22 -383
  6. data/lib/idrac/session.rb +278 -0
  7. data/lib/idrac/version.rb +1 -1
  8. data/lib/idrac/web.rb +187 -0
  9. data/lib/idrac.rb +3 -1
  10. metadata +7 -39
  11. data/.rspec +0 -3
  12. data/Rakefile +0 -17
  13. data/dell_firmware_downloads/Catalog.etag +0 -1
  14. data/dell_firmware_downloads/Catalog.xml +0 -0
  15. data/idrac-0.1.6/.rspec +0 -3
  16. data/idrac-0.1.6/README.md +0 -103
  17. data/idrac-0.1.6/Rakefile +0 -17
  18. data/idrac-0.1.6/bin/console +0 -11
  19. data/idrac-0.1.6/bin/idrac +0 -179
  20. data/idrac-0.1.6/bin/setup +0 -8
  21. data/idrac-0.1.6/idrac.gemspec +0 -51
  22. data/idrac-0.1.6/lib/idrac/client.rb +0 -109
  23. data/idrac-0.1.6/lib/idrac/firmware.rb +0 -366
  24. data/idrac-0.1.6/lib/idrac/version.rb +0 -5
  25. data/idrac-0.1.6/lib/idrac.rb +0 -30
  26. data/idrac-0.1.6/sig/idrac.rbs +0 -4
  27. data/idrac-0.1.7/.rspec +0 -3
  28. data/idrac-0.1.7/README.md +0 -103
  29. data/idrac-0.1.7/Rakefile +0 -17
  30. data/idrac-0.1.7/bin/console +0 -11
  31. data/idrac-0.1.7/bin/idrac +0 -179
  32. data/idrac-0.1.7/bin/setup +0 -8
  33. data/idrac-0.1.7/idrac.gemspec +0 -51
  34. data/idrac-0.1.7/lib/idrac/client.rb +0 -109
  35. data/idrac-0.1.7/lib/idrac/firmware.rb +0 -366
  36. data/idrac-0.1.7/lib/idrac/screenshot.rb +0 -49
  37. data/idrac-0.1.7/lib/idrac/version.rb +0 -5
  38. data/idrac-0.1.7/lib/idrac.rb +0 -30
  39. data/idrac-0.1.7/sig/idrac.rbs +0 -4
  40. data/idrac.py +0 -500
  41. data/lib/idrac/screenshot.rb +0 -49
  42. data/sig/idrac.rbs +0 -4
  43. data/test_firmware_update.rb +0 -68
  44. data/updater.rb +0 -729
@@ -0,0 +1,278 @@
1
+ require 'faraday'
2
+ require 'base64'
3
+ require 'json'
4
+ require 'colorize'
5
+ require 'uri'
6
+
7
+ module IDRAC
8
+ class Session
9
+ attr_reader :host, :username, :password, :port, :use_ssl, :verify_ssl,
10
+ :x_auth_token, :session_location, :direct_mode, :auto_delete_sessions
11
+
12
+ def initialize(client)
13
+ @client = client
14
+ @host = client.host
15
+ @username = client.username
16
+ @password = client.password
17
+ @port = client.port
18
+ @use_ssl = client.use_ssl
19
+ @verify_ssl = client.verify_ssl
20
+ @x_auth_token = nil
21
+ @session_location = nil
22
+ @direct_mode = client.direct_mode
23
+ @sessions_maxed = false
24
+ @auto_delete_sessions = client.auto_delete_sessions
25
+ end
26
+
27
+ def connection
28
+ @connection ||= Faraday.new(url: base_url, ssl: { verify: verify_ssl }) do |faraday|
29
+ faraday.request :multipart
30
+ faraday.request :url_encoded
31
+ faraday.adapter Faraday.default_adapter
32
+ end
33
+ end
34
+
35
+ # Force clear all sessions by directly using Basic Auth
36
+ def force_clear_sessions
37
+ puts "Attempting to force clear all sessions...".light_cyan
38
+
39
+ if delete_all_sessions_with_basic_auth
40
+ puts "Successfully cleared sessions using Basic Auth".green
41
+ true
42
+ else
43
+ puts "Failed to clear sessions using Basic Auth".red
44
+ false
45
+ end
46
+ end
47
+
48
+ # Delete all sessions using Basic Authentication
49
+ def delete_all_sessions_with_basic_auth
50
+ puts "Attempting to delete all sessions using Basic Authentication...".light_cyan
51
+
52
+ # First, get the list of sessions
53
+ sessions_url = '/redfish/v1/SessionService/Sessions'
54
+
55
+ begin
56
+ # Get the list of sessions
57
+ response = request_with_basic_auth(:get, sessions_url)
58
+
59
+ if response.status != 200
60
+ puts "Failed to get sessions list: #{response.status} - #{response.body}".red
61
+ return false
62
+ end
63
+
64
+ # Parse the response to get session IDs
65
+ begin
66
+ sessions_data = JSON.parse(response.body)
67
+
68
+ if sessions_data['Members'] && sessions_data['Members'].any?
69
+ puts "Found #{sessions_data['Members'].count} active sessions".light_yellow
70
+
71
+ # Delete each session
72
+ success = true
73
+ sessions_data['Members'].each do |session|
74
+ session_url = session['@odata.id']
75
+
76
+ # Skip if no URL
77
+ next unless session_url
78
+
79
+ # Delete the session
80
+ delete_response = request_with_basic_auth(:delete, session_url)
81
+
82
+ if delete_response.status == 200 || delete_response.status == 204
83
+ puts "Successfully deleted session: #{session_url}".green
84
+ else
85
+ puts "Failed to delete session #{session_url}: #{delete_response.status}".red
86
+ success = false
87
+ end
88
+
89
+ # Small delay between deletions
90
+ sleep(1)
91
+ end
92
+
93
+ return success
94
+ else
95
+ puts "No active sessions found".light_yellow
96
+ return true
97
+ end
98
+ rescue JSON::ParserError => e
99
+ puts "Error parsing sessions response: #{e.message}".red.bold
100
+ return false
101
+ end
102
+ rescue => e
103
+ puts "Error during session deletion with Basic Auth: #{e.message}".red.bold
104
+ return false
105
+ end
106
+ end
107
+
108
+ # Create a Redfish session
109
+ def create
110
+ # Skip if we're in direct mode
111
+ if @direct_mode
112
+ puts "Skipping Redfish session creation (direct mode)".light_yellow
113
+ return false
114
+ end
115
+
116
+ url = '/redfish/v1/SessionService/Sessions'
117
+ payload = { "UserName" => username, "Password" => password }
118
+
119
+ # Try creation methods in sequence
120
+ return true if create_session_with_content_type(url, payload)
121
+ return true if create_session_with_basic_auth(url, payload)
122
+ return true if handle_max_sessions_and_retry(url, payload)
123
+ return true if create_session_with_form_urlencoded(url, payload)
124
+
125
+ # If all attempts fail, switch to direct mode
126
+ @direct_mode = true
127
+ false
128
+ end
129
+
130
+ # Delete the Redfish session
131
+ def delete
132
+ return unless @x_auth_token && @session_location
133
+
134
+ begin
135
+ puts "Deleting Redfish session...".light_cyan
136
+
137
+ # Use the X-Auth-Token for authentication
138
+ headers = { 'X-Auth-Token' => @x_auth_token }
139
+
140
+ response = connection.delete(@session_location) do |req|
141
+ req.headers.merge!(headers)
142
+ end
143
+
144
+ if response.status == 200 || response.status == 204
145
+ puts "Redfish session deleted successfully".green
146
+ @x_auth_token = nil
147
+ @session_location = nil
148
+ return true
149
+ else
150
+ puts "Failed to delete Redfish session: #{response.status} - #{response.body}".red
151
+ return false
152
+ end
153
+ rescue => e
154
+ puts "Error during Redfish session deletion: #{e.message}".red.bold
155
+ return false
156
+ end
157
+ end
158
+
159
+ private
160
+
161
+ def base_url
162
+ protocol = use_ssl ? 'https' : 'http'
163
+ "#{protocol}://#{host}:#{port}"
164
+ end
165
+
166
+ def basic_auth_headers
167
+ {
168
+ 'Authorization' => "Basic #{Base64.strict_encode64("#{username}:#{password}")}",
169
+ 'Content-Type' => 'application/json'
170
+ }
171
+ end
172
+
173
+ def request_with_basic_auth(method, url, body = nil)
174
+ connection.send(method, url) do |req|
175
+ req.headers.merge!(basic_auth_headers)
176
+ req.body = body if body
177
+ end
178
+ rescue => e
179
+ puts "Error during #{method} request with Basic Auth: #{e.message}".red.bold
180
+ raise e
181
+ end
182
+
183
+ def process_session_response(response)
184
+ if response.status == 201 || response.status == 200
185
+ @x_auth_token = response.headers['X-Auth-Token']
186
+ @session_location = response.headers['Location']
187
+ @sessions_maxed = false
188
+ true
189
+ else
190
+ false
191
+ end
192
+ end
193
+
194
+ def create_session_with_content_type(url, payload)
195
+ begin
196
+ response = connection.post(url) do |req|
197
+ req.headers['Content-Type'] = 'application/json'
198
+ req.body = payload.to_json
199
+ end
200
+
201
+ if process_session_response(response)
202
+ puts "Redfish session created successfully".green
203
+ return true
204
+ end
205
+ rescue => e
206
+ puts "First session creation attempt failed: #{e.message}".light_red
207
+ end
208
+ false
209
+ end
210
+
211
+ def create_session_with_basic_auth(url, payload)
212
+ begin
213
+ response = request_with_basic_auth(:post, url, payload.to_json)
214
+
215
+ if process_session_response(response)
216
+ puts "Redfish session created successfully with Basic Auth".green
217
+ return true
218
+ elsif response.status == 400 && response.body.include?("maximum number of user sessions")
219
+ puts "Maximum sessions reached during Redfish session creation".light_red
220
+ @sessions_maxed = true
221
+ return false
222
+ else
223
+ puts "Failed to create Redfish session: #{response.status} - #{response.body}".red
224
+ return false
225
+ end
226
+ rescue => e
227
+ puts "Error during Redfish session creation with Basic Auth: #{e.message}".red.bold
228
+ return false
229
+ end
230
+ end
231
+
232
+ def handle_max_sessions_and_retry(url, payload)
233
+ return false unless @sessions_maxed && @auto_delete_sessions
234
+
235
+ puts "Auto-delete sessions is enabled, attempting to clear sessions".light_cyan
236
+ if force_clear_sessions
237
+ puts "Successfully cleared sessions, trying to create a new session".green
238
+
239
+ # Try one more time after clearing
240
+ response = request_with_basic_auth(:post, url, payload.to_json)
241
+
242
+ if process_session_response(response)
243
+ puts "Redfish session created successfully after clearing sessions".green
244
+ return true
245
+ else
246
+ puts "Failed to create Redfish session after clearing sessions: #{response.status} - #{response.body}".red
247
+ return false
248
+ end
249
+ else
250
+ puts "Failed to clear sessions, switching to direct mode".light_yellow
251
+ return false
252
+ end
253
+ end
254
+
255
+ def create_session_with_form_urlencoded(url, payload)
256
+ # Only try with form-urlencoded if we had a 415 error previously
257
+ begin
258
+ puts "Trying with form-urlencoded content type".light_cyan
259
+ response = connection.post(url) do |req|
260
+ req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
261
+ req.headers['Authorization'] = "Basic #{Base64.strict_encode64("#{username}:#{password}")}"
262
+ req.body = "UserName=#{URI.encode_www_form_component(username)}&Password=#{URI.encode_www_form_component(password)}"
263
+ end
264
+
265
+ if process_session_response(response)
266
+ puts "Redfish session created successfully with form-urlencoded".green
267
+ return true
268
+ else
269
+ puts "Failed with form-urlencoded too: #{response.status} - #{response.body}".red
270
+ return false
271
+ end
272
+ rescue => e
273
+ puts "Error during form-urlencoded session creation: #{e.message}".red.bold
274
+ return false
275
+ end
276
+ end
277
+ end
278
+ end
data/lib/idrac/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IDRAC
4
- VERSION = "0.1.31"
4
+ VERSION = "0.1.40"
5
5
  end
data/lib/idrac/web.rb ADDED
@@ -0,0 +1,187 @@
1
+ require 'httparty'
2
+ require 'nokogiri'
3
+ require 'uri'
4
+ require 'colorize'
5
+
6
+ module IDRAC
7
+ class Web
8
+ attr_reader :client, :session_id, :cookies
9
+
10
+ def initialize(client)
11
+ @client = client
12
+ @session_id = nil
13
+ @cookies = nil
14
+ @tried_clearing_sessions = false
15
+ end
16
+
17
+ # Login to the WebUI
18
+ def login(retry_count = 0)
19
+ # Limit retries to prevent infinite loops
20
+ if retry_count >= 3
21
+ puts "Maximum retry count reached for WebUI login".red
22
+ return false
23
+ end
24
+
25
+ # Skip if we already have a session ID
26
+ return true if @session_id
27
+
28
+ begin
29
+ puts "Logging in to WebUI...".light_cyan
30
+
31
+ # Create the login URL
32
+ login_url = "#{base_url}/data/login"
33
+
34
+ # Create the login payload
35
+ payload = {
36
+ 'user' => client.username,
37
+ 'password' => client.password
38
+ }
39
+
40
+ # Make the login request
41
+ response = HTTParty.post(
42
+ login_url,
43
+ body: payload,
44
+ verify: client.verify_ssl,
45
+ headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }
46
+ )
47
+
48
+ # Check if the login was successful
49
+ if response.code == 200
50
+ # Extract the session ID from the response
51
+ if response.body.include?('ST2')
52
+ @session_id = response.body.match(/ST2=([^;]+)/)[1]
53
+ @cookies = response.headers['set-cookie']
54
+ puts "WebUI login successful".green
55
+ return response.body
56
+ else
57
+ puts "WebUI login failed: No session ID found in response".red
58
+ return false
59
+ end
60
+ elsif response.code == 400 && response.body.include?("maximum number of user sessions")
61
+ puts "Maximum sessions reached during WebUI login".light_red
62
+
63
+ # Try to clear sessions if auto_delete_sessions is enabled
64
+ if client.auto_delete_sessions && !@tried_clearing_sessions
65
+ puts "Auto-delete sessions is enabled, attempting to clear sessions".light_cyan
66
+ @tried_clearing_sessions = true
67
+
68
+ if client.session.force_clear_sessions
69
+ puts "Successfully cleared sessions, trying WebUI login again".green
70
+ return login(retry_count + 1)
71
+ else
72
+ puts "Failed to clear sessions for WebUI login".red
73
+ return false
74
+ end
75
+ else
76
+ puts "Auto-delete sessions is disabled or already tried clearing".light_yellow
77
+ return false
78
+ end
79
+ else
80
+ puts "WebUI login failed: #{response.code} - #{response.body}".red
81
+ return false
82
+ end
83
+ rescue => e
84
+ puts "Error during WebUI login: #{e.message}".red.bold
85
+ return false
86
+ end
87
+ end
88
+
89
+ # Logout from the WebUI
90
+ def logout
91
+ return unless @session_id
92
+
93
+ begin
94
+ puts "Logging out from WebUI...".light_cyan
95
+
96
+ # Create the logout URL
97
+ logout_url = "#{base_url}/data/logout"
98
+
99
+ # Make the logout request
100
+ response = HTTParty.get(
101
+ logout_url,
102
+ verify: client.verify_ssl,
103
+ headers: { 'Cookie' => @cookies }
104
+ )
105
+
106
+ # Check if the logout was successful
107
+ if response.code == 200
108
+ puts "WebUI logout successful".green
109
+ @session_id = nil
110
+ @cookies = nil
111
+ return true
112
+ else
113
+ puts "WebUI logout failed: #{response.code} - #{response.body}".red
114
+ return false
115
+ end
116
+ rescue => e
117
+ puts "Error during WebUI logout: #{e.message}".red.bold
118
+ return false
119
+ end
120
+ end
121
+
122
+ # Capture a screenshot
123
+ def capture_screenshot
124
+ # Login to get the forward URL and cookies
125
+ forward_url = login
126
+ return nil unless forward_url
127
+
128
+ # Extract the key-value pairs from the forward URL (format: index?ST1=ABC,ST2=DEF)
129
+ tokens = forward_url.split("?").last.split(",").inject({}) do |acc, kv|
130
+ k, v = kv.split("=")
131
+ acc[k] = v
132
+ acc
133
+ end
134
+
135
+ # Generate a timestamp for the request
136
+ timestamp_ms = (Time.now.to_f * 1000).to_i
137
+
138
+ # First request to trigger the screenshot capture
139
+ path = "data?get=consolepreview[manual%20#{timestamp_ms}]"
140
+ res = get(path: path, headers: tokens)
141
+ raise Error, "Failed to trigger screenshot capture." unless res.code.between?(200, 299)
142
+
143
+ # Wait for the screenshot to be generated
144
+ sleep 2
145
+
146
+ # Second request to get the actual screenshot image
147
+ path = "capconsole/scapture0.png?#{timestamp_ms}"
148
+ res = get(path: path, headers: tokens)
149
+ raise Error, "Failed to retrieve screenshot image." unless res.code.between?(200, 299)
150
+
151
+ # Save the screenshot to a file
152
+ filename = "idrac_screenshot_#{timestamp_ms}.png"
153
+ File.open(filename, "wb") { |f| f.write(res.body) }
154
+
155
+ # Return the filename
156
+ filename
157
+ end
158
+
159
+ # HTTP GET request for WebUI operations
160
+ def get(path:, headers: {})
161
+ headers_to_use = {
162
+ "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",
163
+ "Accept-Encoding" => "deflate, gzip"
164
+ }
165
+
166
+ if @cookies
167
+ headers_to_use["Cookie"] = @cookies
168
+ elsif client.direct_mode
169
+ # In direct mode, use Basic Auth
170
+ headers_to_use["Authorization"] = "Basic #{Base64.strict_encode64("#{client.username}:#{client.password}")}"
171
+ end
172
+
173
+ HTTParty.get(
174
+ "#{base_url}/#{path}",
175
+ headers: headers_to_use.merge(headers),
176
+ verify: false
177
+ )
178
+ end
179
+
180
+ private
181
+
182
+ def base_url
183
+ protocol = client.use_ssl ? 'https' : 'http'
184
+ "#{protocol}://#{client.host}:#{client.port}"
185
+ end
186
+ end
187
+ end
data/lib/idrac.rb CHANGED
@@ -6,13 +6,15 @@ require 'faraday'
6
6
  require 'faraday/multipart'
7
7
  require 'base64'
8
8
  require 'uri'
9
+ require 'colorize'
9
10
  # If dev, required debug
10
11
  require 'debug' if ENV['RUBY_ENV'] == 'development'
11
12
 
12
13
  require_relative "idrac/version"
13
14
  require_relative "idrac/error"
15
+ require_relative "idrac/session"
16
+ require_relative "idrac/web"
14
17
  require_relative "idrac/client"
15
- require_relative "idrac/screenshot"
16
18
  require_relative "idrac/firmware"
17
19
  require_relative "idrac/firmware_catalog"
18
20
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: idrac
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.31
4
+ version: 0.1.40
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-03-02 00:00:00.000000000 Z
11
+ date: 2025-04-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -136,14 +136,14 @@ dependencies:
136
136
  requirements:
137
137
  - - "~>"
138
138
  - !ruby/object:Gem::Version
139
- version: '0.8'
139
+ version: '1.1'
140
140
  type: :runtime
141
141
  prerelease: false
142
142
  version_requirements: !ruby/object:Gem::Requirement
143
143
  requirements:
144
144
  - - "~>"
145
145
  - !ruby/object:Gem::Version
146
- version: '0.8'
146
+ version: '1.1'
147
147
  - !ruby/object:Gem::Dependency
148
148
  name: bundler
149
149
  requirement: !ruby/object:Gem::Requirement
@@ -214,51 +214,19 @@ executables:
214
214
  extensions: []
215
215
  extra_rdoc_files: []
216
216
  files:
217
- - ".rspec"
218
217
  - README.md
219
- - Rakefile
220
218
  - bin/console
221
219
  - bin/idrac
222
220
  - bin/setup
223
- - dell_firmware_downloads/Catalog.etag
224
- - dell_firmware_downloads/Catalog.xml
225
- - idrac-0.1.6/.rspec
226
- - idrac-0.1.6/README.md
227
- - idrac-0.1.6/Rakefile
228
- - idrac-0.1.6/bin/console
229
- - idrac-0.1.6/bin/idrac
230
- - idrac-0.1.6/bin/setup
231
- - idrac-0.1.6/idrac.gemspec
232
- - idrac-0.1.6/lib/idrac.rb
233
- - idrac-0.1.6/lib/idrac/client.rb
234
- - idrac-0.1.6/lib/idrac/firmware.rb
235
- - idrac-0.1.6/lib/idrac/version.rb
236
- - idrac-0.1.6/sig/idrac.rbs
237
- - idrac-0.1.7/.rspec
238
- - idrac-0.1.7/README.md
239
- - idrac-0.1.7/Rakefile
240
- - idrac-0.1.7/bin/console
241
- - idrac-0.1.7/bin/idrac
242
- - idrac-0.1.7/bin/setup
243
- - idrac-0.1.7/idrac.gemspec
244
- - idrac-0.1.7/lib/idrac.rb
245
- - idrac-0.1.7/lib/idrac/client.rb
246
- - idrac-0.1.7/lib/idrac/firmware.rb
247
- - idrac-0.1.7/lib/idrac/screenshot.rb
248
- - idrac-0.1.7/lib/idrac/version.rb
249
- - idrac-0.1.7/sig/idrac.rbs
250
221
  - idrac.gemspec
251
- - idrac.py
252
222
  - lib/idrac.rb
253
223
  - lib/idrac/client.rb
254
224
  - lib/idrac/error.rb
255
225
  - lib/idrac/firmware.rb
256
226
  - lib/idrac/firmware_catalog.rb
257
- - lib/idrac/screenshot.rb
227
+ - lib/idrac/session.rb
258
228
  - lib/idrac/version.rb
259
- - sig/idrac.rbs
260
- - test_firmware_update.rb
261
- - updater.rb
229
+ - lib/idrac/web.rb
262
230
  homepage: http://github.com
263
231
  licenses:
264
232
  - MIT
@@ -279,7 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
279
247
  - !ruby/object:Gem::Version
280
248
  version: '0'
281
249
  requirements: []
282
- rubygems_version: 3.4.19
250
+ rubygems_version: 3.5.16
283
251
  signing_key:
284
252
  specification_version: 4
285
253
  summary: API Client for Dell iDRAC
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/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
@@ -1 +0,0 @@
1
- "8e46be845f83db1:0"
Binary file
data/idrac-0.1.6/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper