console-launcher 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NzdlYmU5NTgzZmI5NTlmYzdhYmZiYmQ2OGMwNzQ3MmRmNDA2YjkzNg==
4
+ NTU4NDAyMmFiMTAwNDZjYjNiODRkMTRmODg1MDcxOGFhZjNhYjFkMg==
5
5
  data.tar.gz: !binary |-
6
- MDU4Y2JlNmIxODI1OGE4ODE3Njg2NzJiNzg3OGFmZjFjODA3ZDU5Yw==
6
+ YjQ2ODFhMWNjZWIwNTg3ZjQ0MzIyMmRkNjFjMWJhZTFlNDIxODk5ZQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- YmE0YTFkMWRjZGQ4NjUwZTkzYzcxOWYyYWQ3NTE1ZDY0MTVjMWUyNTJmNjFk
10
- ZmM5MmM1MTZkN2M5NWE3MDVhZTg2NzIyZDZmZWM3OTZiMjZkNzlkNTc0YWZm
11
- ZTUyN2M0NTU2N2ZiMTEyZmFlNjFkZWJiZDk4YWU2Yjg2YjhmNWM=
9
+ MTQ4MDA2ZjEwZDAyZWJmZDMyYzgxMDliNGVkZDNjOWYwOGMzNWNmMmM1Y2U0
10
+ ZjdjYmU2MGEzYzc4ZDZiNDI0OWRjYjVjZTkyMjRmYzMzZDViYmFjZTFiNzFk
11
+ MzkxZmEzZjcyMDNmNjJlMTlmMWUyODExYTQ5ZjhmNTg0NmE4Njc=
12
12
  data.tar.gz: !binary |-
13
- ZGUzYmM3NTRhNTVlYmJlYWI4NjQwZDMxY2Q5YmQ1YzZlYzMzNGQwZGYyYzY3
14
- ZDgyYjIyNjBiMTUzZTZkMThjODg5YzVmZDdjN2FjMjQ3NWRlYTlkMTE2ZTli
15
- ZDJmNGFlMTc3NTNjMDdlZmM3ZGY1MTI3YjY1MTFhZDI0NmVkMDk=
13
+ ZWYzM2U2ZWFjZDlkMWQ3MjhjMWM4MDBjOWE5OTg1ODIxZmU1YTA3MTQ2NzIx
14
+ ZTE2YzE2NzgxN2Y5MzkyMjI0ZGVmMzZlNTYwNmQyODhkNjYzZTMwYzM4Y2M4
15
+ Zjg5NTUwMDc0ZmQ5ODdkYWVlY2JjZWM3ZDIyYjBkNGRmMWRiN2M=
@@ -35,45 +35,30 @@ require 'optparse'
35
35
  require 'yaml'
36
36
  include Helper
37
37
 
38
- options = {
39
- print: false,
40
- dryrun: false,
41
- host: nil,
42
- user: "admin@internal",
43
- pass: nil
44
- }
45
-
46
- CONFIG_FILE = File.join(ENV['HOME'], '.config-launcher.rc.yaml')
47
- if File.exists? CONFIG_FILE
48
- config_options = YAML.load_file(CONFIG_FILE)
49
- options.merge!(config_options)
50
- else
51
- File.open(CONFIG_FILE, 'w') { |file| YAML::dump(options, file) }
52
- STDERR.puts "Initialized configuration file in #{CONFIG_FILE}"
53
- end
38
+ Helper.load_options
54
39
 
55
40
  optparse = OptionParser.new do |opts|
56
41
  opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
57
42
 
58
43
 
59
44
  opts.on('--print', 'Print the command that is called to launch the Console Session') do
60
- options[:print] = true
45
+ Helper::OPTIONS[:print] = true
61
46
  end
62
47
 
63
48
  opts.on('-d', '--dry-run', 'Do not execute the Remote Viewer Application') do
64
- options[:dryrun] = true
49
+ Helper::OPTIONS[:dryrun] = true
65
50
  end
66
51
 
67
52
  opts.on('-h', '--host HOSTNAME', 'The Hostname of your RHEV-M Installation') do |host|
68
- options[:host] = strip_url(host)
53
+ Helper::OPTIONS[:host] = strip_url(host)
69
54
  end
70
55
 
71
56
  opts.on('-u', '--username USERNAME', 'The Username used to establish the connection to --host (defaults to admin@internal)') do |u|
72
- options[:user] = u
57
+ Helper::OPTIONS[:user] = u
73
58
  end
74
59
 
75
60
  opts.on('-p', '--password PASSWORD', 'The Password used to establish the connection to --host') do |pass|
76
- options[:pass] = pass
61
+ Helper::OPTIONS[:pass] = pass
77
62
  end
78
63
 
79
64
  # This displays the help screen, all programs are
@@ -102,15 +87,15 @@ end
102
87
  # the @options. What's left is the list of files to resize.
103
88
  optparse.parse!
104
89
 
105
- if options[:host] == nil
90
+ if Helper::OPTIONS[:host] == nil
106
91
  puts "ERROR: You have to configure RHEV-M Hostname to connect to"
107
92
  puts optparse.help
108
93
  exit 1
109
94
  end
110
95
 
111
- options[:pass] = get_password() if options[:pass] == nil
96
+ Helper::OPTIONS[:pass] = get_password() if Helper::OPTIONS[:pass] == nil
112
97
 
113
- rhevm = RhevManager.new(options[:host], options[:user], options[:pass])
98
+ rhevm = RhevManager.new(Helper::OPTIONS[:host], Helper::OPTIONS[:user], Helper::OPTIONS[:pass])
114
99
 
115
100
  while true do
116
101
  begin
@@ -118,7 +103,7 @@ while true do
118
103
 
119
104
  # Print the selection to the User
120
105
  puts
121
- puts "Running Virtual Machines found for #{options[:host]}:"
106
+ puts "Running Virtual Machines found for #{Helper::OPTIONS[:host]}:"
122
107
  vms.each_with_index do |v, index|
123
108
  puts "#{index+1}. Name: #{v.name} Description: #{v.description} State: #{v.state}"
124
109
  end
@@ -140,8 +125,8 @@ while true do
140
125
 
141
126
  if (1..vms.size).member?(index)
142
127
  command = rhevm.launch_viewer(index)
143
- puts command if options[:print]
144
- unless options[:dryrun]
128
+ puts command if Helper::OPTIONS[:print]
129
+ unless Helper::OPTIONS[:dryrun]
145
130
  pid = Process.fork
146
131
 
147
132
  if pid.nil?
@@ -12,6 +12,12 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ # Author:: Juergen Hoffmann (mailto:buddy@redhat.com)
16
+ # Author:: Vinny Valdez (mailto:vvaldez@redhat.com)
17
+ # Author:: Thomas Crowe (mailto:tcrowe@redhat.com)
18
+ # Copyright:: Copyright (c) 2013 Red Hat Inc.
19
+ # License:: http://www.apache.org/licenses/LICENSE-2.0
20
+
15
21
  require 'rubygems'
16
22
  require 'rest_client'
17
23
  require 'xmlsimple'
@@ -19,121 +25,168 @@ require 'tmpdir' # required to download the certificate files on they fly
19
25
  require 'net/http'
20
26
  require 'highline/import' # Secure Password Prompting if a user does not provide it when the script is called
21
27
  require 'rhev-manager/virtual-machine'
28
+ require 'rbconfig'
29
+
30
+ # This class provides utility methods to encapsulates RESTful access to the RHEV Manager.
31
+ # Since the returned response is in XML this class transforms the XML Response into Ruby Objects.
32
+
33
+ class RhevManager
34
+
35
+ TMP_DIR = Dir.tmpdir
36
+
37
+ def initialize(host, user, password)
38
+ @host = host
39
+ @user = user
40
+ @pass = password
41
+
42
+ # Create a little helper object that we will use to
43
+ # make connections to the REST API
44
+ @rhevm = RestClient::Resource.new(
45
+ "https://" + @host,
46
+ :user => @user,
47
+ :password => @pass,
48
+ :ssl_ca_cert => @cert,
49
+ :ssl_version => "SSLv3",
50
+ :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
51
+ get_cert
52
+ end
22
53
 
23
- class RhevManager
24
-
25
- TMP_DIR = Dir.tmpdir
26
-
27
- def initialize(host, user, password)
28
- @host = host
29
- @user = user
30
- @pass = password
31
-
32
- # Create a little helper object that we will use to
33
- # make connections to the REST API
34
- @rhevm = RestClient::Resource.new(
35
- "https://" + @host,
36
- :user => @user,
37
- :password => @pass,
38
- :ssl_ca_cert => @cert,
39
- :ssl_version => "SSLv3",
40
- :verify_ssl => OpenSSL::SSL::VERIFY_NONE)
41
- get_cert
42
- end
43
-
44
- def get_cert()
45
- # download the certificate file on the fly
46
- begin
47
- cert = File.new(TMP_DIR + "/" + @host + ".crt", "w+")
48
- Net::HTTP.start(@host) do |http|
49
- begin
50
- http.request_get('/ca.crt') do |resp|
51
- resp.read_body do |segment|
52
- cert.write(segment)
53
- end
54
+ # Download the Server SSL Certificate file on the fly
55
+ def get_cert()
56
+ begin
57
+ cert = File.new(TMP_DIR + "/" + @host + ".crt", "w+")
58
+ Net::HTTP.start(@host) do |http|
59
+ begin
60
+ http.request_get('/ca.crt') do |resp|
61
+ resp.read_body do |segment|
62
+ cert.write(segment)
54
63
  end
55
- ensure
56
- cert.close()
57
64
  end
65
+ ensure
66
+ cert.close()
58
67
  end
59
- @cert = cert.path
60
- rescue => e
61
- raise "There has been an error downloading the certificate file from #{@host}: #{e.message}"
62
68
  end
69
+ @cert = cert.path
70
+ rescue => e
71
+ raise "There has been an error downloading the certificate file from #{@host}: #{e.message}"
63
72
  end
73
+ end
64
74
 
65
- def get_vms()
66
- @vms = Array.new # Clear out array
67
- # get the vms api and get the list of vms
68
- vms_data = XmlSimple.xml_in(@rhevm["/api/vms"].get.body, {'ForceArray' => false})
69
-
70
- # Iterate through the VM's and get all the
71
- # required information
72
- vms_data['vm'].each do |vm|
73
- # Making sure we only consider VM's that are in state up (so they do have a console to connect to)
74
- # and that have the spice protocol enabled as the connection mode
75
- if vm['status']['state'] == "up" && vm['display']['type'] == "spice"
76
- @vms.push(VirtualMachine.new(vm))
77
- end
78
- end
79
- return @vms
80
- end
75
+ # Returns an array of VirtualMachine ruby objects that are running on the RHEV Manager
81
76
 
82
- def launch_viewer(index)
83
- vm = @vms[index-1]
84
-
85
- # let us no gather the host subject
86
- hosts_data = XmlSimple.xml_in(@rhevm["/api/hosts/"+vm.host_uuid].get.body, {'ForceArray' => false})
87
- host_subject = hosts_data['certificate']['subject']
88
-
89
- ticket_data = XmlSimple.xml_in(@rhevm["/api/vms/" + vm.id + "/ticket"].post("<action><ticket><expiry>30</expiry></ticket></action>", :content_type => 'application/xml').body, {'ForceArray' => false})
90
- password = ticket_data['ticket']['value']
91
-
92
- # Creating the .vv File for the connection
93
- # download the certificate file on the fly
94
- @vv = File.new(TMP_DIR + "/" + vm.name + ".vv", "w+")
95
- begin
96
- @vv.puts("[virt-viewer]")
97
- @vv.puts("type=spice")
98
- @vv.puts("host=#{vm.address}")
99
- @vv.puts("port=#{vm.port}")
100
- @vv.puts("password=#{password}")
101
- @vv.puts("tls-port=#{vm.secure_port}")
102
- @vv.puts("fullscreen=0")
103
- @vv.puts("title=vm:#{vm.name} - %d - Press SHIFT+F12 to Release Cursor")
104
- @vv.puts("enable-smartcard=0")
105
- @vv.puts("enable-usb-autoshare=1")
106
- @vv.puts("usb-filter=-1,-1,-1,-1,0")
107
- @vv.puts("host-subject=#{host_subject}")
108
- @vv.puts("toggle-fullscreen=shift+f11")
109
- @vv.puts("release-cursor=shift+f12")
110
- ensure
111
- @vv.close()
112
- end
77
+ def get_vms()
78
+ @vms = Array.new # Clear out array
79
+
80
+ # get the vms api and get the list of vms
81
+ vms_data = XmlSimple.xml_in(@rhevm["/api/vms"].get.body, {'ForceArray' => false})
113
82
 
114
- # Now that we have all the information we can print the cmd line
115
- puts "Console to VM: #{vm.name} state: #{vm.state} is started"
83
+ # Iterate through the VM's and get all the
84
+ # required information
85
+ vms_data['vm'].each do |vm|
86
+ # Making sure we only consider VM's that are in state up (so they do have a console to connect to)
87
+ # and that have the spice protocol enabled as the connection mode
88
+ if vm['status']['state'] == "up" && vm['display']['type'] == "spice"
89
+ @vms.push(VirtualMachine.new(vm))
90
+ end
91
+ end
92
+ return @vms
93
+ end
116
94
 
117
- command = "/Applications/RemoteViewer.app/Contents/MacOS/RemoteViewer --spice-ca-file #{@cert} #{@vv.path}"
95
+ # This method takes an index that is used to query the VirtualMachine Array for the VM that is supposed to
96
+ # be started. It then queries the RHEV Manager for the correct subject and then requests a ticket for the
97
+ # console session.
98
+ # It then creates a .vv file that is used to be passed to the RemoteViewer Application. It returns the command
99
+ # to be launched because we fork the process and detach from the RemoteViewer process so we are able to launch
100
+ # more than one Console Session at once.
101
+ def launch_viewer(index)
102
+ vm = @vms[index-1]
103
+
104
+ # let us no gather the host subject
105
+ hosts_data = XmlSimple.xml_in(@rhevm["/api/hosts/"+vm.host_uuid].get.body, {'ForceArray' => false})
106
+ host_subject = hosts_data['certificate']['subject']
107
+
108
+ ticket_data = XmlSimple.xml_in(@rhevm["/api/vms/" + vm.id + "/ticket"].post("<action><ticket><expiry>30</expiry></ticket></action>", :content_type => 'application/xml').body, {'ForceArray' => false})
109
+ password = ticket_data['ticket']['value']
110
+
111
+ # Creating the .vv File for the connection
112
+ # download the certificate file on the fly
113
+ @vv = File.new(TMP_DIR + "/" + vm.name + ".vv", "w+")
114
+ begin
115
+ @vv.puts("[virt-viewer]")
116
+ @vv.puts("type=spice")
117
+ @vv.puts("host=#{vm.address}")
118
+ @vv.puts("port=#{vm.port}")
119
+ @vv.puts("password=#{password}")
120
+ @vv.puts("tls-port=#{vm.secure_port}")
121
+ @vv.puts("fullscreen=0")
122
+ @vv.puts("title=vm:#{vm.name} - %d - Press SHIFT+F12 to Release Cursor")
123
+ @vv.puts("enable-smartcard=0")
124
+ @vv.puts("enable-usb-autoshare=1")
125
+ @vv.puts("usb-filter=-1,-1,-1,-1,0")
126
+ @vv.puts("host-subject=#{host_subject}")
127
+ @vv.puts("toggle-fullscreen=shift+f11")
128
+ @vv.puts("release-cursor=shift+f12")
129
+ ensure
130
+ @vv.close()
118
131
  end
119
132
 
133
+ # Now that we have all the information we can print the cmd line
134
+ puts "Console to VM: #{vm.name} state: #{vm.state} is started"
120
135
 
136
+ command = "#{Helper::OPTIONS[:viewer]} --spice-ca-file #{@cert} #{@vv.path}"
121
137
  end
122
138
 
139
+
140
+ end
141
+
123
142
  module Helper
124
143
 
144
+ CONFIG_FILE = File.join(ENV['HOME'], '.console-launcher.rc.yaml')
145
+
146
+ OPTIONS = {
147
+ print: false,
148
+ dryrun: false,
149
+ host: nil,
150
+ user: "admin@internal",
151
+ pass: nil
152
+ }
153
+
154
+ OPTIONS[:viewer] = case RbConfig::CONFIG['host_os']
155
+ when /mac|darwin/ then
156
+ "/Applications/RemoteViewer.app/Contents/MacOS/RemoteViewer"
157
+ when /linux|bsd|cygwin/ then
158
+ "/usr/bin/remote-viewer"
159
+ when /mswin|mingw/ then
160
+ "C:/Program Files/VirtViewer/bin/remote-viewer.exe"
161
+ # when /solaris|sunos/ then :Linux # needs testing..
162
+ else
163
+ raise "Your OS(#{ RbConfig::CONFIG['host_os'] }) is not yet supported"
164
+ end
165
+
166
+ def load_options
167
+ if File.exists? CONFIG_FILE
168
+ config_options = YAML.load_file(CONFIG_FILE)
169
+ OPTIONS.merge!(config_options)
170
+
171
+ unless config_options.has_key?(:viewer)
172
+ File.open(CONFIG_FILE, 'w') { |file| YAML::dump(OPTIONS, file) }
173
+ end
174
+ else
175
+ File.open(CONFIG_FILE, 'w') { |file| YAML::dump(OPTIONS, file) }
176
+ STDERR.puts "Initialized configuration file in #{CONFIG_FILE}"
177
+ end
178
+ end
179
+
125
180
  # queries the User for a password
126
181
  def get_password(prompt="RHEV-M Password: ")
127
182
  ask(prompt) { |q| q.echo = "*" }
128
183
  end
129
184
 
185
+ # Remove any leading http or https from the host
130
186
  def strip_url(url)
131
- # Remove any leading http or https from the host
132
187
  url = url.split("://")[1] if url.include? "://"
133
188
  return url
134
189
  end
135
190
 
136
- def initialize
137
191
 
138
- end
139
192
  end
@@ -1,4 +1,4 @@
1
1
 
2
2
  module ConsoleLauncher
3
- VERSION = '0.0.8'
3
+ VERSION = '0.0.9'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: console-launcher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juergen Hoffmann
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-05-25 00:00:00.000000000 Z
13
+ date: 2013-05-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rest-client