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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YWY1NjAwYTJkYzk2MjhjM2VlZWMxNzczMjFlNTNiNTZiZGY3ZmM0NA==
5
- data.tar.gz: !binary |-
6
- ZTk0N2I3ZGE2NDUxZDczNmIxYjM0MmM0Y2M4ODVhMWFjOGMyMzU2Mw==
2
+ SHA1:
3
+ metadata.gz: 504a3de86ba14879d18fba08869332df2141d035
4
+ data.tar.gz: c13bbd6aca91f62b9f411a677d96191950af365e
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NmIzNmRkNWU1MzIzZjViZWY1NWI0MzVhM2E5YjdjZmVhNzRmYjBhZjQ4ZDgy
10
- MmY5Nzk0NjA2NTdkNTk0NjA3MjFmMzA4MTFiNzU3YWJjNjZjMmE4ZDVkY2Ji
11
- ZmVkZGY2N2I0NDZiZjNiNjZlMzgzODRjMTc0OWVhOWVhODYyYzk=
12
- data.tar.gz: !binary |-
13
- ZmI5Y2ViMWNiZmY4ZWM2MDY3YjU1NWVkODMzYWQ5Yjg5YmNjNjBmZjEyMThk
14
- ZmEwMjZhMGQ2NGY5NDJhMGNlNDE2NWIxNDk2ODY5YmYyYTQxNDk5NzAyMjcx
15
- ZWUxMjM1ZmE0M2ZhNzE0MDAwOTZkMzgxOGE1ZjA5MDRhYTNmMGI=
6
+ metadata.gz: 916ddac142889f70d803234247a3e0ebd263624e409a85a8086789e721f8d4d96e9f957f09be660dac659e336212c190e244f4e2f7f0acad54b6204f43e395ca
7
+ data.tar.gz: e9c807a19bb8ed8262d23df5d3d50017a4d14c44c9aa691a0c19048c90c41dba597e0b609f67949238a5e6359a3f022d7174a341336dc2cc47201f012976affc
@@ -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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Moob
2
- VERSION = [0,3,16]
2
+ VERSION = [0,4,1]
3
3
  end
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.3.16
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: 2014-09-25 00:00:00.000000000 Z
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.2.2
82
+ rubygems_version: 2.0.14
82
83
  signing_key:
83
84
  specification_version: 4
84
85
  summary: Manage Out-Of-Band!