moob 0.3.4 → 0.3.5

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 (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
+