moob 0.3.3 → 0.3.4
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.
- data/COPYING +12 -3
- data/bin/moob +83 -78
- data/lib/moob.rb +52 -51
- data/lib/moob/baselom.rb +39 -38
- data/lib/moob/ibmeserver.rb +55 -56
- data/lib/moob/idrac6.rb +147 -196
- data/lib/moob/megatrends.rb +65 -65
- data/lib/moob/sunilom.rb +42 -42
- metadata +54 -66
data/lib/moob/idrac6.rb
CHANGED
@@ -1,202 +1,153 @@
|
|
1
1
|
module Moob
|
2
2
|
class Idrac6 < BaseLom
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
vmBootOnce
|
56
|
-
firstBootDevice
|
57
|
-
NicEtherMac1
|
58
|
-
NicEtherMac2
|
59
|
-
NicEtherMac3
|
60
|
-
NicEtherMac4
|
61
|
-
NiciSCSIMac1
|
62
|
-
NiciSCSIMac2
|
63
|
-
NiciSCSIMac3
|
64
|
-
NiciSCSIMac4
|
65
|
-
NicEtherVMac1
|
66
|
-
NicEtherVMac2
|
67
|
-
NicEtherVMac3
|
68
|
-
NicEtherVMac4
|
69
|
-
}
|
70
|
-
|
71
|
-
def initialize hostname, options = {}
|
72
|
-
super hostname, options
|
73
|
-
@username ||= 'root'
|
74
|
-
@password ||= 'calvin'
|
3
|
+
@name = 'Dell iDrac 6'
|
4
|
+
|
5
|
+
INFO_FIELDS = %w[
|
6
|
+
biosVer svcTag expSvcCode hostName
|
7
|
+
osName osVersion sysDesc sysRev datetime initCountdown presentCountdown
|
8
|
+
fwVersion fwUpdated LCCfwVersion
|
9
|
+
firstBootDevice vmBootOnce
|
10
|
+
racName hwVersionmacAddr recoveryAction
|
11
|
+
NicEtherMac1 NicEtherMac2 NicEtherMac3 NicEtherMac4
|
12
|
+
NiciSCSIMac1 NiciSCSIMac2 NiciSCSIMac3 NiciSCSIMac4
|
13
|
+
NicEtherVMac1 NicEtherVMac2 NicEtherVMac3 NicEtherVMac4
|
14
|
+
v4Enabled v4IPAddr v4Gateway v4NetMask
|
15
|
+
v6Enabled v6Addr v6Gateway v6Prefix v6LinkLocal
|
16
|
+
v4DHCPEnabled v4DHCPServers v4DNS1 v4DNS2
|
17
|
+
v6DHCPEnabled v6DHCPServers v6DNS1 v6DNS2
|
18
|
+
v6SiteLocal v6SiteLocal3 v6SiteLocal4 v6SiteLocal5 v6SiteLocal6 v6SiteLocal7 v6SiteLocal8
|
19
|
+
v6SiteLocal9 v6SiteLocal10 v6SiteLocal11 v6SiteLocal12 v6SiteLocal13 v6SiteLocal14 v6SiteLocal15
|
20
|
+
]
|
21
|
+
|
22
|
+
def initialize hostname, options = {}
|
23
|
+
super hostname, options
|
24
|
+
@username ||= 'root'
|
25
|
+
@password ||= 'calvin'
|
26
|
+
end
|
27
|
+
|
28
|
+
def authenticate
|
29
|
+
@session.handle_cookies nil
|
30
|
+
start = @session.get 'start.html'
|
31
|
+
raise ResponseError.new start unless start.status == 200
|
32
|
+
|
33
|
+
auth = @session.post 'data/login',
|
34
|
+
"user=#{@username}&password=#{@password}"
|
35
|
+
raise ResponseError.new auth unless auth.status == 200
|
36
|
+
|
37
|
+
auth.body =~ /<authResult>([^<]+)<\/authResult>/
|
38
|
+
raise 'Cannot find auth result' unless $&
|
39
|
+
raise "Auth failed with: \"#{auth.body}\"" unless $1 == "0"
|
40
|
+
return self
|
41
|
+
end
|
42
|
+
|
43
|
+
def logout
|
44
|
+
out = @session.get 'data/logout'
|
45
|
+
raise ResponseError.new out unless out.status == 200
|
46
|
+
return self
|
47
|
+
end
|
48
|
+
|
49
|
+
def detect
|
50
|
+
begin
|
51
|
+
home = @session.get 'login.html'
|
52
|
+
home.body =~ /Integrated Dell Remote Access Controller 6/
|
53
|
+
rescue
|
54
|
+
false
|
75
55
|
end
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
class_eval %{def #{name}; power_control #{code}; end}
|
151
|
-
end
|
152
|
-
|
153
|
-
[
|
154
|
-
[0, :bnone, 'Do not change the next boot'],
|
155
|
-
[1, :bpxe, 'Boot on PXE once'],
|
156
|
-
[6, :bbios, 'Boot on BIOS setup once'],
|
157
|
-
[15, :blfloppy, 'Boot on Local Floppy/Primary Removable Media once'],
|
158
|
-
[5, :blcd, 'Boot on Local CD/DVD once'],
|
159
|
-
[2, :blhd, 'Boot on Hard Drive once'],
|
160
|
-
[9, :biscsi, 'Boot on NIC BEV iSCSI once'],
|
161
|
-
[7, :bvfloppy, 'Boot on Virtual Floppy once'],
|
162
|
-
[8, :bvcd, 'Boot on Virtual CD/DVD/ISO once'],
|
163
|
-
[16, :blsd, 'Boot on Local SD Card once'],
|
164
|
-
[11, :bvflash, 'Boot on vFlash once']
|
165
|
-
].each do |code, name, desc|
|
166
|
-
action name, desc
|
167
|
-
class_eval %{def #{name}; boot_on #{code}; end}
|
168
|
-
end
|
169
|
-
|
170
|
-
action :pstatus, 'Power status'
|
171
|
-
def pstatus
|
172
|
-
case get_infos(['pwState'])['pwState']
|
173
|
-
when '0'
|
174
|
-
return :off
|
175
|
-
when '1'
|
176
|
-
return :on
|
177
|
-
else
|
178
|
-
return nil
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
action :infos, 'Get system information'
|
183
|
-
def infos
|
184
|
-
return JSON.pretty_generate get_infos INFO_FIELDS
|
185
|
-
end
|
186
|
-
|
187
|
-
def get_infos keys
|
188
|
-
infos = @session.post "data?get=#{keys.join(',')}", {}
|
189
|
-
|
190
|
-
raise ResponseError.new infos unless infos.status == 200
|
191
|
-
raise "The status isn't OK" unless infos.body =~ /<status>ok<\/status>/
|
192
|
-
|
193
|
-
return Hash[keys.collect do |k|
|
194
|
-
if infos.body =~ /<#{k}>(.*?)<\/#{k}>/
|
195
|
-
[k, $1]
|
196
|
-
else
|
197
|
-
[k, nil]
|
198
|
-
end
|
199
|
-
end]
|
56
|
+
end
|
57
|
+
|
58
|
+
action :jnlp, 'Remote control'
|
59
|
+
def jnlp
|
60
|
+
idx = @session.get 'index.html'
|
61
|
+
raise ResponseError.new idx unless idx.status == 200
|
62
|
+
|
63
|
+
idx.body =~ /var DnsName += +"([^"]+)"/
|
64
|
+
raise "Couldn't find the DNS name" unless $&
|
65
|
+
dns_name = $1
|
66
|
+
|
67
|
+
idx.body =~ /var sysNameStr += +"([^"]+)"/
|
68
|
+
raise "Couldn't find the system name" unless $&
|
69
|
+
sys_name = $1 # eg PowerEdge R610
|
70
|
+
|
71
|
+
# eg escaped "idrac-A1BCD2E, PowerEdge R610, User:root"
|
72
|
+
title = CGI::escape "#{dns_name}, #{sys_name}, User:#{@username}"
|
73
|
+
|
74
|
+
viewer = @session.get "viewer.jnlp(#{@hostname}@0@#{title}@#{Time.now.to_i * 1000})"
|
75
|
+
raise ResponseError.new viewer unless viewer.status == 200
|
76
|
+
|
77
|
+
return viewer.body
|
78
|
+
end
|
79
|
+
|
80
|
+
def power_control action
|
81
|
+
req = @session.post "data?set=pwState:#{action}", {}
|
82
|
+
raise ResponseError.new req unless req.status == 200
|
83
|
+
return nil
|
84
|
+
end
|
85
|
+
|
86
|
+
def boot_on level
|
87
|
+
req = @session.post "data?set=vmBootOnce:1,firstBootDevice:#{level}", {}
|
88
|
+
raise ResponseError.new req unless req.status == 200
|
89
|
+
return nil
|
90
|
+
end
|
91
|
+
|
92
|
+
[
|
93
|
+
[0, :poff, 'Power Off System'],
|
94
|
+
[1, :pon, 'Power On System'],
|
95
|
+
[2, :pcycle, 'Power Cycle System (cold boot)'],
|
96
|
+
[3, :preset, 'Reset System (warm boot)'],
|
97
|
+
[4, :nmi, 'NMI (Non-Masking Interrupt)'],
|
98
|
+
[5, :shutdown, 'Graceful Shutdown']
|
99
|
+
].each do |code, name, desc|
|
100
|
+
action name, desc
|
101
|
+
class_eval %{def #{name}; power_control #{code}; end}
|
102
|
+
end
|
103
|
+
|
104
|
+
[
|
105
|
+
[0, :bnone, 'Do not change the next boot'],
|
106
|
+
[1, :bpxe, 'Boot on PXE once'],
|
107
|
+
[6, :bbios, 'Boot on BIOS setup once'],
|
108
|
+
[15, :blfloppy, 'Boot on Local Floppy/Primary Removable Media once'],
|
109
|
+
[5, :blcd, 'Boot on Local CD/DVD once'],
|
110
|
+
[2, :blhd, 'Boot on Hard Drive once'],
|
111
|
+
[9, :biscsi, 'Boot on NIC BEV iSCSI once'],
|
112
|
+
[7, :bvfloppy, 'Boot on Virtual Floppy once'],
|
113
|
+
[8, :bvcd, 'Boot on Virtual CD/DVD/ISO once'],
|
114
|
+
[16, :blsd, 'Boot on Local SD Card once'],
|
115
|
+
[11, :bvflash, 'Boot on vFlash once']
|
116
|
+
].each do |code, name, desc|
|
117
|
+
action name, desc
|
118
|
+
class_eval %{def #{name}; boot_on #{code}; end}
|
119
|
+
end
|
120
|
+
|
121
|
+
action :pstatus, 'Power status'
|
122
|
+
def pstatus
|
123
|
+
case get_infos(['pwState'])['pwState']
|
124
|
+
when '0'
|
125
|
+
return :off
|
126
|
+
when '1'
|
127
|
+
return :on
|
128
|
+
else
|
129
|
+
return nil
|
200
130
|
end
|
131
|
+
end
|
132
|
+
|
133
|
+
action :infos, 'Get system information'
|
134
|
+
def infos
|
135
|
+
return JSON.pretty_generate get_infos INFO_FIELDS
|
136
|
+
end
|
137
|
+
|
138
|
+
def get_infos keys
|
139
|
+
infos = @session.post "data?get=#{keys.join(',')}", {}
|
140
|
+
|
141
|
+
raise ResponseError.new infos unless infos.status == 200
|
142
|
+
raise "The status isn't OK" unless infos.body =~ /<status>ok<\/status>/
|
143
|
+
|
144
|
+
return Hash[keys.collect do |k|
|
145
|
+
if infos.body =~ /<#{k}>(.*?)<\/#{k}>/
|
146
|
+
[k, $1]
|
147
|
+
else
|
148
|
+
[k, nil]
|
149
|
+
end
|
150
|
+
end]
|
151
|
+
end
|
201
152
|
end
|
202
153
|
end
|
data/lib/moob/megatrends.rb
CHANGED
@@ -1,84 +1,84 @@
|
|
1
1
|
module Moob
|
2
2
|
class Megatrends < BaseLom
|
3
|
-
|
3
|
+
@name = 'American Megatrends'
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
14
|
-
@session.base_url = "https://#{@ip}/"
|
5
|
+
def initialize hostname, options = {}
|
6
|
+
super hostname, options
|
7
|
+
@username ||= 'root'
|
8
|
+
@password ||= 'superuser'
|
9
|
+
begin
|
10
|
+
@ip = Socket.getaddrinfo(hostname, nil)[0][3]
|
11
|
+
rescue
|
12
|
+
raise "Couldn't resolve \"#{hostname}\""
|
15
13
|
end
|
14
|
+
@session.base_url = "#{@transport}://#{@ip}/"
|
15
|
+
end
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
def authenticate
|
18
|
+
auth = @session.post 'rpc/WEBSES/create.asp',
|
19
|
+
{ 'WEBVAR_USERNAME' => @username, 'WEBVAR_PASSWORD' => @password }
|
20
20
|
|
21
|
-
|
21
|
+
raise ResponseError.new auth unless auth.status == 200
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
auth.body =~ /'SESSION_COOKIE' *: *'([^']+)'/
|
24
|
+
raise "Couldn't find auth cookie in \"#{auth.body}\"" unless $&
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
@cookie = "test=1; path=/; SessionCookie=#{$1}"
|
27
|
+
return self
|
28
|
+
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
end
|
30
|
+
def detect
|
31
|
+
begin
|
32
|
+
home = @session.get 'page/login.html'
|
33
|
+
home.body =~ /\.\.\/res\/banner_right\.png/
|
34
|
+
rescue
|
35
|
+
false
|
37
36
|
end
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
action :jnlp, 'Remote control'
|
40
|
+
def jnlp
|
41
|
+
@session.ignore_content_length = true
|
42
|
+
viewer = @session.get 'Java/jviewer.jnlp', { 'Cookie' => @cookie }
|
43
|
+
raise ResponseError.new viewer unless viewer.status == 200
|
44
44
|
|
45
|
-
|
46
|
-
|
45
|
+
return viewer.body
|
46
|
+
end
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
56
|
-
return nil
|
48
|
+
def power_action action
|
49
|
+
req = @session.post 'rpc/hostctl.asp',
|
50
|
+
{ 'WEBVAR_POWER_CMD' => action },
|
51
|
+
{ 'Cookie' => @cookie }
|
52
|
+
raise ResponseError.new req unless req.status == 200
|
53
|
+
unless req.body =~ /WEBVAR_STRUCTNAME_HL_POWERSTATUS/
|
54
|
+
raise 'The answer looks wrong'
|
57
55
|
end
|
56
|
+
return nil
|
57
|
+
end
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
59
|
+
action :poff, 'Power Off'
|
60
|
+
action :pon, 'Power On'
|
61
|
+
action :pcycle, 'Power Cycle'
|
62
|
+
action :preset, 'Power Reset'
|
63
|
+
action :shutdown, 'Soft Power Off'
|
64
|
+
def poff; power_action 0; end
|
65
|
+
def pon; power_action 1; end
|
66
|
+
def pcycle; power_action 2; end
|
67
|
+
def preset; power_action 3; end
|
68
|
+
def soft_poff; power_action 5; end
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
70
|
+
action :pstatus, 'Power status'
|
71
|
+
def pstatus
|
72
|
+
status = @session.get 'rpc/hoststatus.asp',
|
73
|
+
{ 'Cookie' => @cookie }
|
74
|
+
raise ResponseError.new status unless status.status == 200
|
75
|
+
raise 'Couldn\'t read the state' unless status.body =~ /'JF_STATE' : (.),/
|
76
|
+
case $1
|
77
|
+
when '0'
|
78
|
+
return :off
|
79
|
+
when '1'
|
80
|
+
return :on
|
82
81
|
end
|
82
|
+
end
|
83
83
|
end
|
84
84
|
end
|