moob 0.3.16 → 0.4.1
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 +5 -13
- data/lib/moob.rb +5 -1
- data/lib/moob/idrac8.rb +257 -0
- data/lib/moob/version.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZTk0N2I3ZGE2NDUxZDczNmIxYjM0MmM0Y2M4ODVhMWFjOGMyMzU2Mw==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 504a3de86ba14879d18fba08869332df2141d035
|
4
|
+
data.tar.gz: c13bbd6aca91f62b9f411a677d96191950af365e
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
MmY5Nzk0NjA2NTdkNTk0NjA3MjFmMzA4MTFiNzU3YWJjNjZjMmE4ZDVkY2Ji
|
11
|
-
ZmVkZGY2N2I0NDZiZjNiNjZlMzgzODRjMTc0OWVhOWVhODYyYzk=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZmI5Y2ViMWNiZmY4ZWM2MDY3YjU1NWVkODMzYWQ5Yjg5YmNjNjBmZjEyMThk
|
14
|
-
ZmEwMjZhMGQ2NGY5NDJhMGNlNDE2NWIxNDk2ODY5YmYyYTQxNDk5NzAyMjcx
|
15
|
-
ZWUxMjM1ZmE0M2ZhNzE0MDAwOTZkMzgxOGE1ZjA5MDRhYTNmMGI=
|
6
|
+
metadata.gz: 916ddac142889f70d803234247a3e0ebd263624e409a85a8086789e721f8d4d96e9f957f09be660dac659e336212c190e244f4e2f7f0acad54b6204f43e395ca
|
7
|
+
data.tar.gz: e9c807a19bb8ed8262d23df5d3d50017a4d14c44c9aa691a0c19048c90c41dba597e0b609f67949238a5e6359a3f022d7174a341336dc2cc47201f012976affc
|
data/lib/moob.rb
CHANGED
@@ -16,6 +16,8 @@ module Moob
|
|
16
16
|
autoload :BaseLom, 'moob/baselom.rb'
|
17
17
|
autoload :Idrac6, 'moob/idrac6.rb'
|
18
18
|
autoload :Idrac7, 'moob/idrac7.rb'
|
19
|
+
autoload :Idrac8, 'moob/idrac8.rb'
|
20
|
+
autoload :Pec, 'moob/pec.rb'
|
19
21
|
autoload :Megatrends, 'moob/megatrends.rb'
|
20
22
|
autoload :SunILom, 'moob/sunilom.rb'
|
21
23
|
autoload :IbmEServer, 'moob/ibmeserver.rb'
|
@@ -24,13 +26,15 @@ module Moob
|
|
24
26
|
TYPES = {
|
25
27
|
:idrac6 => Idrac6,
|
26
28
|
:idrac7 => Idrac7,
|
29
|
+
:idrac8 => Idrac8,
|
30
|
+
:pec => Pec,
|
27
31
|
:megatrends => Megatrends,
|
28
32
|
:sun => SunILom,
|
29
33
|
:ibm => IbmEServer,
|
30
34
|
:supermicro => Supermicro
|
31
35
|
}
|
32
36
|
|
33
|
-
AUTODETECT_ORDER = [ :idrac7, :idrac6, :supermicro, :megatrends, :sun, :ibm ]
|
37
|
+
AUTODETECT_ORDER = [ :idrac8, :idrac7, :idrac6, :pec, :supermicro, :megatrends, :sun, :ibm ]
|
34
38
|
|
35
39
|
def self.lom type, hostname, options = {}
|
36
40
|
case type
|
data/lib/moob/idrac8.rb
ADDED
@@ -0,0 +1,257 @@
|
|
1
|
+
require 'zlib'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Moob
|
5
|
+
|
6
|
+
class Idrac8 < BaseLom
|
7
|
+
@name = 'Dell iDrac 8'
|
8
|
+
|
9
|
+
|
10
|
+
INFO_FIELDS = %w[
|
11
|
+
biosVer svcTag expSvcCode hostName
|
12
|
+
osName osVersion sysDesc sysRev datetime initCountdown presentCountdown
|
13
|
+
fwVersion fwUpdated LCCfwVersion
|
14
|
+
firstBootDevice vmBootOnce
|
15
|
+
racName hwVersionmacAddr recoveryAction
|
16
|
+
NicEtherMac1 NicEtherMac2 NicEtherMac3 NicEtherMac4
|
17
|
+
NiciSCSIMac1 NiciSCSIMac2 NiciSCSIMac3 NiciSCSIMac4
|
18
|
+
NicEtherVMac1 NicEtherVMac2 NicEtherVMac3 NicEtherVMac4
|
19
|
+
v4Enabled v4IPAddr v4Gateway v4NetMask
|
20
|
+
v6Enabled v6Addr v6Gateway v6Prefix v6LinkLocal
|
21
|
+
v4DHCPEnabled v4DHCPServers v4DNS1 v4DNS2
|
22
|
+
v6DHCPEnabled v6DHCPServers v6DNS1 v6DNS2
|
23
|
+
v6SiteLocal v6SiteLocal3 v6SiteLocal4 v6SiteLocal5 v6SiteLocal6 v6SiteLocal7 v6SiteLocal8
|
24
|
+
v6SiteLocal9 v6SiteLocal10 v6SiteLocal11 v6SiteLocal12 v6SiteLocal13 v6SiteLocal14 v6SiteLocal15
|
25
|
+
ipmiLAN ipmiMinPriv ipmiKey hostname
|
26
|
+
]
|
27
|
+
|
28
|
+
def initialize hostname, options = {}
|
29
|
+
super hostname, options
|
30
|
+
@username ||= 'root'
|
31
|
+
@password ||= 'calvin'
|
32
|
+
@index = nil
|
33
|
+
|
34
|
+
@skiplogout = false
|
35
|
+
|
36
|
+
@session.headers['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
|
37
|
+
@session.headers['Accept-Language'] = 'en-US,en;q=0.8,sv;q=0.6'
|
38
|
+
# idrac8 responds with a 404 if the request is sent for html is sent without encoding headers
|
39
|
+
@session.headers['Accept-Encoding'] = 'gzip,deflate,sdch'
|
40
|
+
end
|
41
|
+
|
42
|
+
def authenticate
|
43
|
+
@session.handle_cookies nil
|
44
|
+
|
45
|
+
login = @session.get 'login.html'
|
46
|
+
|
47
|
+
raise ResponseError.new login unless login.status == 200
|
48
|
+
|
49
|
+
auth = @session.post 'data/login', "user=#{@username}&password=#{@password}"
|
50
|
+
|
51
|
+
raise ResponseError.new auth unless auth.status == 200
|
52
|
+
|
53
|
+
auth.body =~ /<authResult>([^<]+)<\/authResult>/
|
54
|
+
|
55
|
+
raise 'Cannot find auth result' unless $&
|
56
|
+
raise "Auth failed with: \"#{auth.body}\"" unless $1 == "0"
|
57
|
+
|
58
|
+
auth.body =~ /<forwardUrl>([^<]+)<\/forwardUrl>/
|
59
|
+
|
60
|
+
raise 'Cannot find the authenticated index url after auth' unless $&
|
61
|
+
|
62
|
+
@indexurl = $1
|
63
|
+
|
64
|
+
if @indexurl =~ /defaultCred/
|
65
|
+
@indexurl.gsub!(/defaultCred/,'index')
|
66
|
+
Moob.warn "iDRAC recommends you should change the default credentials!"
|
67
|
+
end
|
68
|
+
|
69
|
+
Moob.inform "Requesting indexurl of #{@indexurl}"
|
70
|
+
|
71
|
+
# someone decided it was a good idea to include a ST2 token in every XHR
|
72
|
+
# request. We need it for a lot of our features.
|
73
|
+
@authhash = @indexurl.split('?')[1]
|
74
|
+
@authhash =~ /ST2=([0-9a-f]+)/
|
75
|
+
@st2 = $1
|
76
|
+
|
77
|
+
if @st2.nil?
|
78
|
+
Moob.inform 'Trying to parse ST2 token from HTML page'
|
79
|
+
|
80
|
+
@index = @session.get @indexurl
|
81
|
+
@index.body =~ /var TOKEN_VALUE = "([0-9a-f]+)";/
|
82
|
+
raise ResponseError.new @index unless @index.status == 200
|
83
|
+
@st2 = $1
|
84
|
+
end
|
85
|
+
|
86
|
+
@session.headers['ST2'] = @st2
|
87
|
+
|
88
|
+
return self
|
89
|
+
end
|
90
|
+
|
91
|
+
def logout
|
92
|
+
if @skiplogout
|
93
|
+
Moob.inform 'Skipping logout...'
|
94
|
+
else
|
95
|
+
out = @session.get 'data/logout'
|
96
|
+
raise ResponseError.new out unless out.status == 200
|
97
|
+
end
|
98
|
+
return self
|
99
|
+
end
|
100
|
+
|
101
|
+
def decompress_response response
|
102
|
+
gz_reader = Zlib::GzipReader.new(StringIO.new(response))
|
103
|
+
gz_reader.read
|
104
|
+
end
|
105
|
+
|
106
|
+
def detect
|
107
|
+
begin
|
108
|
+
home = @session.get 'login.html'
|
109
|
+
# patron doesn't (always?) decompress the body automatically
|
110
|
+
begin
|
111
|
+
response = decompress_response home.body
|
112
|
+
rescue Zlib::GzipFile::Error
|
113
|
+
response = home.body
|
114
|
+
end
|
115
|
+
response =~ /(Integrated Dell Remote Access Controller 8)|(iDRAC8)/
|
116
|
+
rescue Exception => e
|
117
|
+
false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
action :jnlp, 'Remote control'
|
122
|
+
|
123
|
+
def jnlp
|
124
|
+
# Request system name and hostname from data end-point
|
125
|
+
req = get_infos ['sysDesc' ,'hostname']
|
126
|
+
|
127
|
+
# eg escaped "idrac-A1BCD2E, PowerEdge R610, User:root"
|
128
|
+
title = CGI::escape "#{req['hostname']}, #{req['sysDesc']}, User:#{@username}"
|
129
|
+
|
130
|
+
viewer = @session.get "viewer.jnlp(#{@hostname}@0@#{title}@#{Time.now.to_i * 1000}@#{@authhash})"
|
131
|
+
raise ResponseError.new viewer unless viewer.status == 200
|
132
|
+
|
133
|
+
return viewer.body
|
134
|
+
end
|
135
|
+
|
136
|
+
def power_control action
|
137
|
+
req = @session.post "data?set=pwState:#{action}", {}
|
138
|
+
raise ResponseError.new req unless req.status == 200
|
139
|
+
return nil
|
140
|
+
end
|
141
|
+
|
142
|
+
def boot_on level
|
143
|
+
req = @session.post "data?set=vmBootOnce:1,firstBootDevice:#{level}", {}
|
144
|
+
raise ResponseError.new req unless req.status == 200
|
145
|
+
return nil
|
146
|
+
end
|
147
|
+
|
148
|
+
[
|
149
|
+
[0, :poff, 'Power Off System'],
|
150
|
+
[1, :pon, 'Power On System'],
|
151
|
+
[2, :pcycle, 'Power Cycle System (cold boot)'],
|
152
|
+
[3, :preset, 'Reset System (warm boot)'],
|
153
|
+
[4, :nmi, 'NMI (Non-Masking Interrupt)'],
|
154
|
+
[5, :shutdown, 'Graceful Shutdown']
|
155
|
+
].each do |code, name, desc|
|
156
|
+
action name, desc
|
157
|
+
class_eval %{def #{name}; power_control #{code}; end}
|
158
|
+
end
|
159
|
+
|
160
|
+
[
|
161
|
+
[0, :bnone, 'Do not change the next boot'],
|
162
|
+
[1, :bpxe, 'Boot on PXE once'],
|
163
|
+
[6, :bbios, 'Boot on BIOS setup once'],
|
164
|
+
[15, :blfloppy, 'Boot on Local Floppy/Primary Removable Media once'],
|
165
|
+
[5, :blcd, 'Boot on Local CD/DVD once'],
|
166
|
+
[2, :blhd, 'Boot on Hard Drive once'],
|
167
|
+
[9, :biscsi, 'Boot on NIC BEV iSCSI once'],
|
168
|
+
[7, :bvfloppy, 'Boot on Virtual Floppy once'],
|
169
|
+
[8, :bvcd, 'Boot on Virtual CD/DVD/ISO once'],
|
170
|
+
[16, :blsd, 'Boot on Local SD Card once'],
|
171
|
+
[17, :bvbios, 'Boot on BIOS Boot Manager once'],
|
172
|
+
[18, :bvlc, 'Boot on Life Cycle Controller once']
|
173
|
+
].each do |code, name, desc|
|
174
|
+
action name, desc
|
175
|
+
class_eval %{def #{name}; boot_on #{code}; end}
|
176
|
+
end
|
177
|
+
|
178
|
+
action :pstatus, 'Power status'
|
179
|
+
def pstatus
|
180
|
+
case get_infos(['pwState'])['pwState']
|
181
|
+
when '0'
|
182
|
+
return :off
|
183
|
+
when '1'
|
184
|
+
return :on
|
185
|
+
else
|
186
|
+
return nil
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
action :infos, 'Get system information'
|
191
|
+
def infos
|
192
|
+
return JSON.pretty_generate get_infos INFO_FIELDS
|
193
|
+
end
|
194
|
+
|
195
|
+
def get_infos keys
|
196
|
+
Moob.inform "Requesting data?get=#{keys.join(',')}"
|
197
|
+
infos = @session.post "data?get=#{keys.join(',')}", {}
|
198
|
+
|
199
|
+
raise ResponseError.new infos unless infos.status == 200
|
200
|
+
raise "The status isn't OK" unless infos.body =~ /<status>ok<\/status>/
|
201
|
+
|
202
|
+
return Hash[keys.collect do |k|
|
203
|
+
if infos.body =~ /<#{k}>(.*?)<\/#{k}>/
|
204
|
+
[k, $1]
|
205
|
+
else
|
206
|
+
[k, nil]
|
207
|
+
end
|
208
|
+
end]
|
209
|
+
end
|
210
|
+
|
211
|
+
action :set_params, 'Set iDRAC parameters'
|
212
|
+
def set_params
|
213
|
+
unless @params
|
214
|
+
raise "Params are not set!"
|
215
|
+
end
|
216
|
+
drac_set_params @params
|
217
|
+
end
|
218
|
+
|
219
|
+
action :enable_ipmi, 'Enable IPMI over LAN (on LOM port)'
|
220
|
+
def enable_ipmi
|
221
|
+
drac_set_params({ 'ipmiLAN' => 1 })
|
222
|
+
end
|
223
|
+
|
224
|
+
def drac_set_params params
|
225
|
+
params.each do |p,v|
|
226
|
+
req = @session.post "data?set=#{p}:#{v}", {}
|
227
|
+
raise ResponseError.new req unless req.status == 200
|
228
|
+
end
|
229
|
+
return nil
|
230
|
+
end
|
231
|
+
|
232
|
+
action :show_console_preview, 'Display iDRAC console screenshot'
|
233
|
+
action :save_console_preview, 'Save iDRAC console screenshot'
|
234
|
+
|
235
|
+
def fetch_console_preview
|
236
|
+
imgfile = Tempfile.new('console_preview')
|
237
|
+
|
238
|
+
refreshreq = @session.get "data?get=consolepreview[auto%20#{Time.now.utc.to_i}]", {}
|
239
|
+
|
240
|
+
raise ResponseError.new req unless refreshreq.status == 200
|
241
|
+
|
242
|
+
req = @session.get_file "capconsole/scapture0.png?#{Time.now.utc.to_i}", imgfile.path
|
243
|
+
|
244
|
+
raise ResponseError.new req unless req.status == 200
|
245
|
+
raise UnexpectedContentError.new req unless req.headers['Content-type'] =~ /image\//
|
246
|
+
|
247
|
+
return imgfile, req.headers
|
248
|
+
end
|
249
|
+
|
250
|
+
action :lomreset, 'Reset LOM'
|
251
|
+
def lomreset
|
252
|
+
@skiplogout = true
|
253
|
+
drac_set_params({ 'iDracReset' => 1 })
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
end
|
data/lib/moob/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moob
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Ferch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: patron
|
@@ -46,18 +46,19 @@ executables:
|
|
46
46
|
extensions: []
|
47
47
|
extra_rdoc_files: []
|
48
48
|
files:
|
49
|
-
- COPYING
|
50
49
|
- bin/moob
|
51
|
-
- lib/moob.rb
|
52
50
|
- lib/moob/baselom.rb
|
53
51
|
- lib/moob/ibmeserver.rb
|
54
52
|
- lib/moob/idrac6.rb
|
55
53
|
- lib/moob/idrac7.rb
|
54
|
+
- lib/moob/idrac8.rb
|
56
55
|
- lib/moob/megatrends.rb
|
57
56
|
- lib/moob/pec.rb
|
58
57
|
- lib/moob/sunilom.rb
|
59
58
|
- lib/moob/supermicro.rb
|
60
59
|
- lib/moob/version.rb
|
60
|
+
- lib/moob.rb
|
61
|
+
- COPYING
|
61
62
|
homepage: https://github.com/spotify/moob
|
62
63
|
licenses:
|
63
64
|
- ISC
|
@@ -68,17 +69,17 @@ require_paths:
|
|
68
69
|
- lib
|
69
70
|
required_ruby_version: !ruby/object:Gem::Requirement
|
70
71
|
requirements:
|
71
|
-
- -
|
72
|
+
- - '>='
|
72
73
|
- !ruby/object:Gem::Version
|
73
74
|
version: '0'
|
74
75
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
76
|
requirements:
|
76
|
-
- -
|
77
|
+
- - '>='
|
77
78
|
- !ruby/object:Gem::Version
|
78
79
|
version: 1.2.0
|
79
80
|
requirements: []
|
80
81
|
rubyforge_project: moob
|
81
|
-
rubygems_version: 2.
|
82
|
+
rubygems_version: 2.0.14
|
82
83
|
signing_key:
|
83
84
|
specification_version: 4
|
84
85
|
summary: Manage Out-Of-Band!
|