moob 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/COPYING ADDED
@@ -0,0 +1,4 @@
1
+ Copyright (c) 2011, Pierre Carrier <pierre@gcarrier.fr>
2
+
3
+ Permission is granted to copy, modify and/or distribute this work and/or
4
+ license, without conditions.
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
@@ -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
@@ -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
@@ -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
+