moob 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/bin/moob +18 -13
  2. data/lib/moob.rb +6 -4
  3. data/lib/moob/idrac7.rb +177 -0
  4. metadata +66 -46
data/bin/moob CHANGED
@@ -87,21 +87,26 @@ begin
87
87
  lom.authenticate
88
88
  Moob.inform "Authenticated on #{h}."
89
89
 
90
- options[:actions].each do |action|
91
- action = action.to_sym
92
- Moob.inform "Trying to perform #{action} on #{h}..."
93
- case action
94
- when :jnlp
95
- Moob.start_jnlp lom
96
- else
97
- res = lom.send action
98
- puts res if res
90
+ begin
91
+ options[:actions].each do |action|
92
+ action = action.to_sym
93
+
94
+ Moob.inform "Trying to perform #{action} on #{h}..."
95
+
96
+ case action
97
+ when :jnlp
98
+ Moob.start_jnlp lom
99
+ else
100
+ res = lom.send action
101
+ puts res if res
102
+ end
103
+
104
+ Moob.inform "Performed #{action} on #{h}."
99
105
  end
100
- Moob.inform "Performed #{action} on #{h}."
106
+ ensure
107
+ lom.logout
108
+ Moob.inform "Logged out of #{h}."
101
109
  end
102
-
103
- lom.logout
104
- Moob.inform "Logged out of #{h}."
105
110
  end
106
111
  puts 'There might be a delay before Java Web Start shows up...' if options[:action] == :jnlp
107
112
 
@@ -1,5 +1,5 @@
1
1
  module Moob
2
- VERSION = [0,3,4]
2
+ VERSION = [0,3,5]
3
3
 
4
4
  class ResponseError < Exception
5
5
  def initialize response
@@ -12,15 +12,17 @@ module Moob
12
12
 
13
13
  autoload :BaseLom, 'moob/baselom.rb'
14
14
  autoload :Idrac6, 'moob/idrac6.rb'
15
+ autoload :Idrac7, 'moob/idrac7.rb'
15
16
  autoload :Megatrends, 'moob/megatrends.rb'
16
17
  autoload :SunILom, 'moob/sunilom.rb'
17
18
  autoload :IbmEServer, 'moob/ibmeserver.rb'
18
19
 
19
20
  TYPES = {
20
- :idrac6 => Idrac6,
21
+ :idrac6 => Idrac6,
22
+ :idrac7 => Idrac7,
21
23
  :megatrends => Megatrends,
22
- :sun => SunILom,
23
- :ibm => IbmEServer
24
+ :sun => SunILom,
25
+ :ibm => IbmEServer
24
26
  }
25
27
 
26
28
  def self.lom type, hostname, options = {}
@@ -0,0 +1,177 @@
1
+ module Moob
2
+ class Idrac7 < BaseLom
3
+ @name = 'Dell iDrac 7'
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
+ @index = nil
27
+ end
28
+
29
+ def authenticate
30
+ @session.handle_cookies("./cookies.txt")
31
+
32
+ login = @session.get 'login.html'
33
+
34
+ raise ResponseError.new login unless login.status == 200
35
+
36
+ auth = @session.post 'data/login', "user=#{@username}&password=#{@password}"
37
+
38
+ raise ResponseError.new auth unless auth.status == 200
39
+
40
+ auth.body =~ /<authResult>([^<]+)<\/authResult>/
41
+
42
+ raise 'Cannot find auth result' unless $&
43
+ raise "Auth failed with: \"#{auth.body}\"" unless $1 == "0"
44
+
45
+ auth.body =~ /<forwardUrl>([^<]+)<\/forwardUrl>/
46
+
47
+ raise 'Cannot find the authenticated index url after auth' unless $&
48
+
49
+ @indexurl = $1
50
+ @authhash = @indexurl.split('?')[1]
51
+
52
+ @index = @session.get @indexurl
53
+
54
+ # someone decided it was a good idea to include a ST2 token in every XHR
55
+ # request. We need it for a lot of our features.
56
+ @index.body =~ /var TOKEN_VALUE = "([0-9a-f]+)";/
57
+ raise ResponseError.new @index unless @index.status == 200
58
+ @st2 = $1
59
+
60
+ @session.headers['ST2'] = @st2
61
+
62
+ puts @authhash
63
+ puts @indexurl
64
+ puts "ST2: #{@st2}"
65
+
66
+ return self
67
+ end
68
+
69
+ def logout
70
+ out = @session.get 'data/logout'
71
+ raise ResponseError.new out unless out.status == 200
72
+ return self
73
+ end
74
+
75
+ def detect
76
+ begin
77
+ home = @session.get 'login.html'
78
+ home.body =~ /Integrated Dell Remote Access Controller 7/
79
+ rescue
80
+ false
81
+ end
82
+ end
83
+
84
+ action :jnlp, 'Remote control'
85
+
86
+ def jnlp
87
+ @index.body =~ /var tmpHN += +"([^"]+)"/
88
+ raise "Couldn't find the DNS name" unless $&
89
+ dns_name = $1
90
+
91
+ @index.body =~ /var sysNameStr += +"([^"]+)"/
92
+ raise "Couldn't find the system name" unless $&
93
+ sys_name = $1 # eg PowerEdge R610
94
+
95
+ # eg escaped "idrac-A1BCD2E, PowerEdge R610, User:root"
96
+ title = CGI::escape "#{dns_name}, #{sys_name}, User:#{@username}"
97
+
98
+ viewer = @session.get "viewer.jnlp(#{@hostname}@0@#{title}@#{Time.now.to_i * 1000}@#{@authhash})"
99
+ raise ResponseError.new viewer unless viewer.status == 200
100
+
101
+ return viewer.body
102
+ end
103
+
104
+ def power_control action
105
+ req = @session.post "data?set=pwState:#{action}", {}
106
+ raise ResponseError.new req unless req.status == 200
107
+ return nil
108
+ end
109
+
110
+ def boot_on level
111
+ req = @session.post "data?set=vmBootOnce:1,firstBootDevice:#{level}", {}
112
+ raise ResponseError.new req unless req.status == 200
113
+ return nil
114
+ end
115
+
116
+ [
117
+ [0, :poff, 'Power Off System'],
118
+ [1, :pon, 'Power On System'],
119
+ [2, :pcycle, 'Power Cycle System (cold boot)'],
120
+ [3, :preset, 'Reset System (warm boot)'],
121
+ [4, :nmi, 'NMI (Non-Masking Interrupt)'],
122
+ [5, :shutdown, 'Graceful Shutdown']
123
+ ].each do |code, name, desc|
124
+ action name, desc
125
+ class_eval %{def #{name}; power_control #{code}; end}
126
+ end
127
+
128
+ [
129
+ [0, :bnone, 'Do not change the next boot'],
130
+ [1, :bpxe, 'Boot on PXE once'],
131
+ [6, :bbios, 'Boot on BIOS setup once'],
132
+ [15, :blfloppy, 'Boot on Local Floppy/Primary Removable Media once'],
133
+ [5, :blcd, 'Boot on Local CD/DVD once'],
134
+ [2, :blhd, 'Boot on Hard Drive once'],
135
+ [9, :biscsi, 'Boot on NIC BEV iSCSI once'],
136
+ [7, :bvfloppy, 'Boot on Virtual Floppy once'],
137
+ [8, :bvcd, 'Boot on Virtual CD/DVD/ISO once'],
138
+ [16, :blsd, 'Boot on Local SD Card once'],
139
+ [11, :bvflash, 'Boot on vFlash once']
140
+ ].each do |code, name, desc|
141
+ action name, desc
142
+ class_eval %{def #{name}; boot_on #{code}; end}
143
+ end
144
+
145
+ action :pstatus, 'Power status'
146
+ def pstatus
147
+ case get_infos(['pwState'])['pwState']
148
+ when '0'
149
+ return :off
150
+ when '1'
151
+ return :on
152
+ else
153
+ return nil
154
+ end
155
+ end
156
+
157
+ action :infos, 'Get system information'
158
+ def infos
159
+ return JSON.pretty_generate get_infos INFO_FIELDS
160
+ end
161
+
162
+ def get_infos keys
163
+ infos = @session.post "data?get=#{keys.join(',')}", {}
164
+
165
+ raise ResponseError.new infos unless infos.status == 200
166
+ raise "The status isn't OK" unless infos.body =~ /<status>ok<\/status>/
167
+
168
+ return Hash[keys.collect do |k|
169
+ if infos.body =~ /<#{k}>(.*?)<\/#{k}>/
170
+ [k, $1]
171
+ else
172
+ [k, nil]
173
+ end
174
+ end]
175
+ end
176
+ end
177
+ end
metadata CHANGED
@@ -1,87 +1,107 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: moob
3
- version: !ruby/object:Gem::Version
4
- version: 0.3.4
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 3
9
+ - 5
10
+ version: 0.3.5
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Pierre Carrier
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-04-26 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-09-07 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: patron
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ~>
20
- - !ruby/object:Gem::Version
21
- version: 0.4.14
22
- type: :runtime
23
22
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
23
+ requirement: &id001 !ruby/object:Gem::Requirement
25
24
  none: false
26
- requirements:
25
+ requirements:
27
26
  - - ~>
28
- - !ruby/object:Gem::Version
27
+ - !ruby/object:Gem::Version
28
+ hash: 19
29
+ segments:
30
+ - 0
31
+ - 4
32
+ - 14
29
33
  version: 0.4.14
30
- - !ruby/object:Gem::Dependency
31
- name: json
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ~>
36
- - !ruby/object:Gem::Version
37
- version: 1.5.3
38
34
  type: :runtime
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: json
39
38
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
39
+ requirement: &id002 !ruby/object:Gem::Requirement
41
40
  none: false
42
- requirements:
41
+ requirements:
43
42
  - - ~>
44
- - !ruby/object:Gem::Version
43
+ - !ruby/object:Gem::Version
44
+ hash: 5
45
+ segments:
46
+ - 1
47
+ - 5
48
+ - 3
45
49
  version: 1.5.3
50
+ type: :runtime
51
+ version_requirements: *id002
46
52
  description: Control systems using Web-based out-of-band managers without a browser
47
- email:
53
+ email:
48
54
  - pierre@spotify.com
49
- executables:
55
+ executables:
50
56
  - moob
51
57
  extensions: []
58
+
52
59
  extra_rdoc_files: []
53
- files:
60
+
61
+ files:
54
62
  - bin/moob
55
- - lib/moob/sunilom.rb
56
- - lib/moob/idrac6.rb
57
- - lib/moob/ibmeserver.rb
58
63
  - lib/moob/baselom.rb
64
+ - lib/moob/ibmeserver.rb
65
+ - lib/moob/idrac6.rb
66
+ - lib/moob/sunilom.rb
59
67
  - lib/moob/megatrends.rb
68
+ - lib/moob/idrac7.rb
60
69
  - lib/moob.rb
61
70
  - COPYING
62
71
  homepage: https://github.com/spotify/moob
63
- licenses:
72
+ licenses:
64
73
  - ISC
65
74
  post_install_message:
66
75
  rdoc_options: []
67
- require_paths:
76
+
77
+ require_paths:
68
78
  - lib
69
- required_ruby_version: !ruby/object:Gem::Requirement
79
+ required_ruby_version: !ruby/object:Gem::Requirement
70
80
  none: false
71
- requirements:
72
- - - ! '>='
73
- - !ruby/object:Gem::Version
74
- version: '0'
75
- required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
89
  none: false
77
- requirements:
78
- - - ! '>='
79
- - !ruby/object:Gem::Version
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ hash: 31
94
+ segments:
95
+ - 1
96
+ - 2
97
+ - 0
80
98
  version: 1.2.0
81
99
  requirements: []
100
+
82
101
  rubyforge_project: moob
83
- rubygems_version: 1.8.23
102
+ rubygems_version: 1.8.15
84
103
  signing_key:
85
104
  specification_version: 3
86
105
  summary: Manage Out-Of-Band!
87
106
  test_files: []
107
+