moob 0.1.0
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 +4 -0
- data/bin/moob +49 -0
- data/lib/moob.rb +48 -0
- data/lib/moob/baselom.rb +34 -0
- data/lib/moob/idrac6.rb +49 -0
- data/lib/moob/megatrends.rb +37 -0
- data/lib/moob/sunilom.rb +33 -0
- metadata +91 -0
data/COPYING
ADDED
data/bin/moob
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'moob'
|
5
|
+
|
6
|
+
options = {
|
7
|
+
:action => :jnlp,
|
8
|
+
:type => :idrac6,
|
9
|
+
:machines => []
|
10
|
+
}
|
11
|
+
|
12
|
+
OptionParser.new do |opts|
|
13
|
+
opts.on '-l', '--list',
|
14
|
+
'List LOM types' do
|
15
|
+
Moob::TYPES.each do |k, v|
|
16
|
+
puts "#{k} (#{v.name})"
|
17
|
+
end
|
18
|
+
exit 0
|
19
|
+
end
|
20
|
+
opts.on '-t', '--type t',
|
21
|
+
'LOM type (idrac6 by default)' do |t|
|
22
|
+
options[:type] = t.to_sym
|
23
|
+
end
|
24
|
+
opts.on '-u', '--username u',
|
25
|
+
'LOM username' do |u|
|
26
|
+
options[:username] = u
|
27
|
+
end
|
28
|
+
opts.on '-p', '--password p',
|
29
|
+
'LOM password' do |p|
|
30
|
+
options[:password] = p
|
31
|
+
end
|
32
|
+
|
33
|
+
opts.on '-m', '--machines a,b,c', Array,
|
34
|
+
'Comma-separated list of machines' do |m|
|
35
|
+
options[:machines] = m
|
36
|
+
end
|
37
|
+
end.parse!
|
38
|
+
|
39
|
+
if options[:machines].empty?
|
40
|
+
$stderr.puts 'No machines selected.'
|
41
|
+
exit 1
|
42
|
+
end
|
43
|
+
|
44
|
+
options[:machines].each do |h|
|
45
|
+
case options[:action]
|
46
|
+
when :jnlp
|
47
|
+
Moob.start_jnlp options[:type], h, options
|
48
|
+
end
|
49
|
+
end
|
data/lib/moob.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'cgi'
|
3
|
+
require 'patron'
|
4
|
+
|
5
|
+
module Moob
|
6
|
+
VERSION = [0,1,0]
|
7
|
+
|
8
|
+
autoload :BaseLom, 'moob/baselom.rb'
|
9
|
+
autoload :Idrac6, 'moob/idrac6.rb'
|
10
|
+
autoload :Megatrends, 'moob/megatrends.rb'
|
11
|
+
autoload :SunILom, 'moob/sunilom.rb'
|
12
|
+
|
13
|
+
TYPES = {
|
14
|
+
:idrac6 => Idrac6,
|
15
|
+
:megatrends => Megatrends,
|
16
|
+
:sun => SunILom
|
17
|
+
}
|
18
|
+
|
19
|
+
class ResponseError < Exception
|
20
|
+
def initialize response
|
21
|
+
@response = response
|
22
|
+
end
|
23
|
+
def to_s
|
24
|
+
"#{@response.url} failed (status #{@response.status})"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.start_jnlp type, hostname, options = {}
|
29
|
+
|
30
|
+
lom = TYPES[type].new hostname, options
|
31
|
+
jnlp = lom.authenticate.jnlp
|
32
|
+
|
33
|
+
unless jnlp[/<\/jnlp>/]
|
34
|
+
raise RuntimeError.new "Invalid JNLP file (\"#{jnlp}\")"
|
35
|
+
end
|
36
|
+
|
37
|
+
filepath = "/tmp/#{hostname}.jnlp"
|
38
|
+
File.open filepath, 'w' do |f|
|
39
|
+
f.write jnlp
|
40
|
+
end
|
41
|
+
|
42
|
+
system "javaws #{filepath}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.cmdline
|
46
|
+
start_jnlp :megatrends, 'brenda.lom.sto.spotify.net'
|
47
|
+
end
|
48
|
+
end
|
data/lib/moob/baselom.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
class Moob::BaseLom
|
2
|
+
@@name = 'Unknown'
|
3
|
+
|
4
|
+
def initialize hostname, options = {}
|
5
|
+
@hostname = hostname
|
6
|
+
@username = options[:username]
|
7
|
+
@password = options[:password]
|
8
|
+
|
9
|
+
@session = Patron::Session.new
|
10
|
+
@session.headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; '\
|
11
|
+
'Intel Mac OS X 10.7; rv:5.0.1) Gecko/20100101 Firefox/5.0.1'
|
12
|
+
@session.base_url = "https://#{hostname}/"
|
13
|
+
@session.connect_timeout = 10_000
|
14
|
+
@session.timeout = 10_000
|
15
|
+
@session.insecure = true
|
16
|
+
@session.ignore_content_length = true
|
17
|
+
end
|
18
|
+
|
19
|
+
def jnlp
|
20
|
+
raise new NoMethodError
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.name
|
24
|
+
@@name
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
# Get rid of security checks.
|
29
|
+
# Might break some features,
|
30
|
+
# please let me know if that's the case!
|
31
|
+
def desecurize_jnlp jnlp
|
32
|
+
jnlp.sub /<security>.*<\/security>/m, ''
|
33
|
+
end
|
34
|
+
end
|
data/lib/moob/idrac6.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
class Moob::Idrac6 < Moob::BaseLom
|
2
|
+
@@name = 'Dell iDrac 6'
|
3
|
+
|
4
|
+
def initialize hostname, options = {}
|
5
|
+
super hostname, options
|
6
|
+
@username ||= 'root'
|
7
|
+
@password ||= 'calvin'
|
8
|
+
end
|
9
|
+
|
10
|
+
def authenticate
|
11
|
+
@session.handle_cookies nil
|
12
|
+
start = @session.get 'start.html'
|
13
|
+
raise ResponseError.new start unless start.status == 200
|
14
|
+
|
15
|
+
auth = @session.post 'data/login',
|
16
|
+
"user=#{@username}&password=#{@password}"
|
17
|
+
raise ResponseError.new auth unless auth.status == 200
|
18
|
+
|
19
|
+
result_match = auth.body.match /<authResult>([^<]+)<\/authResult>/
|
20
|
+
raise Exception.new 'Cannot find auth result' unless result_match
|
21
|
+
result_code = result_match[1]
|
22
|
+
unless result_code == "0"
|
23
|
+
raise Exception.new "Auth failed with: \"#{auth.body}\""
|
24
|
+
end
|
25
|
+
return self
|
26
|
+
end
|
27
|
+
|
28
|
+
def jnlp
|
29
|
+
idx = @session.get 'index.html'
|
30
|
+
raise ResponseError.new idx unless idx.status == 200
|
31
|
+
|
32
|
+
name_match = idx.body.match /var DnsName += +"([^"]+)"/
|
33
|
+
raise Exception.new 'Couldn\'t find the DNS name' unless name_match
|
34
|
+
dns_name = name_match[1]
|
35
|
+
|
36
|
+
sys_match = idx.body.match /var sysNameStr += +"([^"]+)"/
|
37
|
+
raise Exception.new 'Couldn\'t find the system name' unless name_match
|
38
|
+
sys_name = sys_match[1] # eg PowerEdge R610
|
39
|
+
|
40
|
+
# eg escaped "idrac-D4MHZ4J, PowerEdge R610, User:root"
|
41
|
+
title = CGI::escape "#{dns_name}, #{sys_name}, User:#{@username}"
|
42
|
+
path = "viewer.jnlp(#{@hostname}@0@#{title}@#{Time.now.to_i * 1000})"
|
43
|
+
|
44
|
+
viewer = @session.get path
|
45
|
+
raise ResponseError.new viewer unless viewer.status == 200
|
46
|
+
|
47
|
+
return desecurize_jnlp viewer.body
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Moob::Megatrends < Moob::BaseLom
|
2
|
+
@@name = 'American Megatrends'
|
3
|
+
|
4
|
+
def initialize hostname, options = {}
|
5
|
+
super hostname, options
|
6
|
+
@username ||= 'root'
|
7
|
+
@password ||= 'superuser'
|
8
|
+
begin
|
9
|
+
@ip = Socket.getaddrinfo(hostname, nil)[0][2]
|
10
|
+
rescue
|
11
|
+
raise Exception.new "Couldn't resolve \"#{hostname}\""
|
12
|
+
end
|
13
|
+
@session.base_url = "https://#{@ip}/"
|
14
|
+
end
|
15
|
+
|
16
|
+
def authenticate
|
17
|
+
auth = @session.post 'rpc/WEBSES/create.asp',
|
18
|
+
{ 'WEBVAR_USERNAME' => @username, 'WEBVAR_PASSWORD' => @password }
|
19
|
+
|
20
|
+
raise ResponseError.new auth unless auth.status == 200
|
21
|
+
|
22
|
+
cookie_match = auth.body.match /'SESSION_COOKIE' *: *'([^']+)'/
|
23
|
+
unless cookie_match
|
24
|
+
raise Exception.new "Couldn't find auth cookie in \"#{auth.body}\""
|
25
|
+
end
|
26
|
+
|
27
|
+
@cookie = "test=1; path=/; SessionCookie=#{cookie_match[1]}"
|
28
|
+
return self
|
29
|
+
end
|
30
|
+
|
31
|
+
def jnlp
|
32
|
+
viewer = @session.get 'Java/jviewer.jnlp', { 'Cookie' => @cookie }
|
33
|
+
raise ResponseError.new viewer unless viewer.status == 200
|
34
|
+
|
35
|
+
return desecurize_jnlp viewer.body
|
36
|
+
end
|
37
|
+
end
|
data/lib/moob/sunilom.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
class Moob::SunILom < Moob::BaseLom
|
2
|
+
@@name = 'Sun Integrated Lights Out Manager'
|
3
|
+
|
4
|
+
def initialize hostname, options = {}
|
5
|
+
super hostname, options
|
6
|
+
@username ||= 'root'
|
7
|
+
@password ||= 'changeme'
|
8
|
+
end
|
9
|
+
|
10
|
+
def authenticate
|
11
|
+
auth = @session.post 'iPages/loginProcessor.asp', {
|
12
|
+
'username' => @username,
|
13
|
+
'password' => @password
|
14
|
+
}
|
15
|
+
|
16
|
+
raise ResponseError.new auth unless auth.status == 200
|
17
|
+
|
18
|
+
cookie_match = auth.body.match /SetWebSessionString\("([^"]+)","([^"]+)"\);/
|
19
|
+
unless cookie_match
|
20
|
+
raise Exception.new "Couldn't find session cookie in \"#{auth.body}\""
|
21
|
+
end
|
22
|
+
|
23
|
+
@cookie = "#{cookie_match[1]}=#{cookie_match[2]}; langsetting=EN"
|
24
|
+
return self
|
25
|
+
end
|
26
|
+
|
27
|
+
def jnlp
|
28
|
+
viewer = @session.get 'cgi-bin/jnlpgenerator-8', { 'Cookie' => @cookie }
|
29
|
+
raise ResponseError.new viewer unless viewer.status == 200
|
30
|
+
|
31
|
+
return viewer.body
|
32
|
+
end
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: moob
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Pierre Carrier
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-07-25 00:00:00 +02:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: patron
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 21
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 4
|
33
|
+
- 13
|
34
|
+
version: 0.4.13
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
description: Control systems using Web-based out-of-band managers without a browser
|
38
|
+
email:
|
39
|
+
- pierre@gcarrier.fr
|
40
|
+
executables:
|
41
|
+
- moob
|
42
|
+
extensions: []
|
43
|
+
|
44
|
+
extra_rdoc_files: []
|
45
|
+
|
46
|
+
files:
|
47
|
+
- bin/moob
|
48
|
+
- lib/moob/baselom.rb
|
49
|
+
- lib/moob/idrac6.rb
|
50
|
+
- lib/moob/megatrends.rb
|
51
|
+
- lib/moob/sunilom.rb
|
52
|
+
- lib/moob.rb
|
53
|
+
- COPYING
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://github.com/pcarrier/moob
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 23
|
78
|
+
segments:
|
79
|
+
- 1
|
80
|
+
- 3
|
81
|
+
- 6
|
82
|
+
version: 1.3.6
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project: moob
|
86
|
+
rubygems_version: 1.6.2
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Manage Out-Of-Band!
|
90
|
+
test_files: []
|
91
|
+
|