lab 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.gitignore +4 -0
  2. data/config/test_lab.yml +11 -0
  3. data/config/test_targets.yml +21 -0
  4. data/lib/lab/controller/dynagen_controller.rb +6 -6
  5. data/lib/lab/controller/remote_esx_controller.rb +51 -51
  6. data/lib/lab/controller/remote_esxi_controller.rb +62 -0
  7. data/lib/lab/controller/remote_workstation_controller.rb +12 -12
  8. data/lib/lab/controller/virtualbox_controller.rb +16 -16
  9. data/lib/lab/controller/workstation_controller.rb +9 -9
  10. data/lib/lab/controller/workstation_vixr_controller.rb +9 -9
  11. data/lib/lab/controllers.rb +1 -3
  12. data/lib/lab/driver/dynagen_driver.rb +32 -32
  13. data/lib/lab/driver/fog_driver.rb +144 -144
  14. data/lib/lab/driver/remote_esxi_driver.rb +177 -0
  15. data/lib/lab/driver/remote_workstation_driver.rb +181 -181
  16. data/lib/lab/driver/virtualbox_driver.rb +132 -132
  17. data/lib/lab/driver/vm_driver.rb +177 -177
  18. data/lib/lab/driver/workstation_driver.rb +218 -218
  19. data/lib/lab/driver/workstation_vixr_driver.rb +108 -108
  20. data/lib/lab/drivers.rb +1 -1
  21. data/lib/lab/modifier/backtrack5_modifier.rb +8 -8
  22. data/lib/lab/modifier/dos_modifier.rb +3 -3
  23. data/lib/lab/modifier/test_modifier.rb +6 -6
  24. data/lib/lab/version.rb +1 -1
  25. data/lib/lab/vm.rb +242 -242
  26. data/lib/lab/vm_controller.rb +217 -211
  27. data/src/Gemfile +4 -0
  28. data/src/README.md +80 -0
  29. data/src/Rakefile +1 -0
  30. data/src/TODO +15 -0
  31. data/src/config/test_lab.yml +11 -0
  32. data/src/config/test_targets.yml +21 -0
  33. data/src/lab.gemspec +35 -0
  34. data/src/lib/lab.rb +2 -0
  35. data/src/lib/lab/controller/dynagen_controller.rb +14 -0
  36. data/src/lib/lab/controller/fog_controller.rb +6 -0
  37. data/src/lib/lab/controller/remote_esxi_controller.rb +62 -0
  38. data/src/lib/lab/controller/remote_workstation_controller.rb +22 -0
  39. data/src/lib/lab/controller/virtualbox_controller.rb +25 -0
  40. data/src/lib/lab/controller/vsphere_controller.rb +18 -0
  41. data/src/lib/lab/controller/workstation_controller.rb +17 -0
  42. data/src/lib/lab/controller/workstation_vixr_controller.rb +19 -0
  43. data/src/lib/lab/controllers.rb +9 -0
  44. data/src/lib/lab/driver/dynagen_driver.rb +47 -0
  45. data/src/lib/lab/driver/fog_driver.rb +104 -0
  46. data/src/lib/lab/driver/remote_esxi_driver.rb +177 -0
  47. data/src/lib/lab/driver/remote_workstation_driver.rb +197 -0
  48. data/src/lib/lab/driver/virtualbox_driver.rb +142 -0
  49. data/src/lib/lab/driver/vm_driver.rb +195 -0
  50. data/src/lib/lab/driver/vsphere_driver.rb +120 -0
  51. data/src/lib/lab/driver/workstation_driver.rb +234 -0
  52. data/src/lib/lab/driver/workstation_vixr_driver.rb +126 -0
  53. data/src/lib/lab/drivers.rb +9 -0
  54. data/src/lib/lab/modifier/backtrack5_modifier.rb +16 -0
  55. data/src/lib/lab/modifier/dos_modifier.rb +14 -0
  56. data/src/lib/lab/modifier/test_modifier.rb +16 -0
  57. data/src/lib/lab/modifiers.rb +3 -0
  58. data/src/lib/lab/version.rb +3 -0
  59. data/src/lib/lab/vm.rb +269 -0
  60. data/src/lib/lab/vm_controller.rb +275 -0
  61. data/src/test/.gitkeep +0 -0
  62. metadata +51 -12
  63. data/lib/lab/driver/remote_esx_driver.rb +0 -177
@@ -0,0 +1,195 @@
1
+ ##
2
+ ## $Id$
3
+ ##
4
+
5
+ #
6
+ # !!WARNING!! - All drivers are expected to filter input before running
7
+ # anything based on it. This is particularly important in the case
8
+ # of the drivers which wrap a command line to provide functionality.
9
+ #
10
+
11
+ module Lab
12
+ module Drivers
13
+ class VmDriver
14
+
15
+ attr_accessor :vmid
16
+ attr_accessor :location
17
+ attr_accessor :os
18
+ attr_accessor :tools
19
+ attr_accessor :credentials
20
+
21
+ def initialize(config)
22
+
23
+ @vmid = filter_command(config["vmid"].to_s)
24
+ @location = filter_command(config["location"])
25
+ @credentials = config["credentials"] || []
26
+ @tools = filter_input(config["tools"])
27
+ @arch = filter_input(config["arch"])
28
+ @os = filter_input(config["os"])
29
+ @hostname = filter_input(config["hostname"]) || filter_input(config["vmid"].to_s)
30
+
31
+ # Currently only implemented for the first set
32
+ if @credentials.count > 0
33
+ @vm_user = filter_input(@credentials[0]['user'])
34
+ @vm_pass = filter_input(@credentials[0]['pass'])
35
+ @vm_keyfile = filter_input(@credentials[0]['keyfile'])
36
+ end
37
+ end
38
+
39
+ ## This interface must be implemented in a child driver class
40
+ ## #########################################################
41
+
42
+ def register
43
+ raise "Command not Implemented"
44
+ end
45
+
46
+ def unregister
47
+ raise "Command not Implemented"
48
+ end
49
+
50
+ def start
51
+ raise "Command not Implemented"
52
+ end
53
+
54
+ def stop
55
+ raise "Command not Implemented"
56
+ end
57
+
58
+ def suspend
59
+ raise "Command not Implemented"
60
+ end
61
+
62
+ def pause
63
+ raise "Command not Implemented"
64
+ end
65
+
66
+ def resume
67
+ raise "Command not Implemented"
68
+ end
69
+
70
+ def reset
71
+ raise "Command not Implemented"
72
+ end
73
+
74
+ def create_snapshot(snapshot)
75
+ raise "Command not Implemented"
76
+ end
77
+
78
+ def revert_snapshot(snapshot)
79
+ raise "Command not Implemented"
80
+ end
81
+
82
+ def delete_snapshot(snapshot)
83
+ raise "Command not Implemented"
84
+ end
85
+
86
+ def run_command(command)
87
+ raise "Command not Implemented"
88
+ end
89
+
90
+ def copy_from(from, to)
91
+ raise "Command not Implemented"
92
+ end
93
+
94
+ def copy_to(from, to)
95
+ raise "Command not Implemented"
96
+ end
97
+
98
+ def check_file_exists(file)
99
+ raise "Command not Implemented"
100
+ end
101
+
102
+ def create_directory(directory)
103
+ raise "Command not Implemented"
104
+ end
105
+
106
+ def cleanup
107
+ raise "Command not Implemented"
108
+ end
109
+
110
+ ## End Interface
111
+ ## #########################################################
112
+
113
+ private
114
+
115
+ # The only reason we don't filter here is because we need
116
+ # the ability to still run clean (controlled entirely by us)
117
+ # command lines.
118
+ def system_command(command)
119
+ puts "DEBUG: system command #{command}"
120
+ system(command)
121
+ end
122
+
123
+ def remote_system_command(command)
124
+ puts "DEBUG: remote system command #{command} running with user #{@user}@#{@host}"
125
+ system_command("ssh #{@user}@#{@host} \"#{command}\"")
126
+ end
127
+
128
+ def scp_to(local,remote)
129
+ if @vm_keyfile
130
+ #puts "DEBUG: authenticating to #{@hostname} as #{@vm_user} with key #{@vm_keyfile}"
131
+ Net::SCP.start(@hostname, @vm_user, :keys => [@vm_keyfile]) do |scp|
132
+ puts "DEBUG: uploading #{local} to #{remote}"
133
+ scp.upload!(local,remote)
134
+ end
135
+ else
136
+ Net::SCP.start(@hostname, @vm_user, :password => @vm_pass, :auth_methods => ["password"]) do |scp|
137
+ puts "DEBUG: uploading #{local} to #{remote}"
138
+ scp.upload!(local,remote)
139
+ end
140
+ end
141
+ end
142
+
143
+ def scp_from(remote, local)
144
+ # download a file from a remote server
145
+ if @vm_keyfile
146
+ #puts "DEBUG: authenticating to #{@hostname} as #{@vm_user} with key #{@vm_keyfile}"
147
+ Net::SCP.start(@hostname, @vm_user, :keys => [@vm_keyfile]) do |scp|
148
+ puts "DEBUG: downloading #{remote} to #{local}"
149
+ scp.download!(remote,local)
150
+ end
151
+ else
152
+ Net::SCP.start(@hostname, @vm_user, :password => @vm_pass, :auth_methods => ["password"]) do |scp|
153
+ puts "DEBUG: downloading #{remote} to #{local}"
154
+ scp.download!(remote,local)
155
+ end
156
+ end
157
+ end
158
+
159
+ def ssh_exec(command)
160
+ if @vm_keyfile
161
+ #puts "DEBUG: authenticating to #{@hostname} as #{@vm_user} with key #{@vm_keyfile}"
162
+ Net::SSH.start(@hostname, @vm_user, :keys => [@vm_keyfile]) do |ssh|
163
+ puts "DEBUG: running command: #{command}"
164
+ ssh.exec!(command)
165
+ end
166
+ else
167
+ Net::SSH.start(@hostname, @vm_user, :password => @vm_pass, :auth_methods => ["password"]) do |ssh|
168
+ result = ssh.exec!(command)
169
+ end
170
+ end
171
+ end
172
+
173
+ def filter_input(string)
174
+ return "" unless string # nil becomes empty string
175
+ return unless string.class == String # Allow other types unmodified
176
+
177
+ unless /^[\d\w\s\[\]\{\}\/\\\.\-\"\(\):!]*$/.match string
178
+ raise "WARNING! Invalid character in: #{string}"
179
+ end
180
+ string
181
+ end
182
+
183
+ def filter_command(string)
184
+ return "" unless string # nil becomes empty string
185
+ return unless string.class == String # Allow other types unmodified
186
+
187
+ unless /^[\d\w\s\[\]\{\}\/\\\.\-\"\(\)]*$/.match string
188
+ raise "WARNING! Invalid character in: #{string}"
189
+ end
190
+ string
191
+ end
192
+
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,120 @@
1
+ require 'vm_driver'
2
+
3
+ ##
4
+ ## $Id$
5
+ ##
6
+
7
+ # This driver was built against:
8
+ # VMware Vsphere 4.1
9
+
10
+ module Lab
11
+ module Drivers
12
+
13
+ class VsphereDriver < VmDriver
14
+
15
+ def initialize(config)
16
+ unless config['user'] then raise ArgumentError, "Must provide a username" end
17
+ unless config['host'] then raise ArgumentError, "Must provide a hostname" end
18
+ unless config[''] then raise ArgumentError, "Must provide a password" end
19
+ super(config)
20
+
21
+ @user = filter_command(config['user'])
22
+ @host = filter_command(config['host'])
23
+
24
+ # Soft dependency
25
+ begin
26
+ require 'rbvmomi'
27
+ rescue LoadError
28
+ raise "WARNING: Library rbvmomi not found. Could not create driver!"
29
+ end
30
+
31
+ vim = RbVmomi::VIM.connect host: @host, user: @user, password: @pass
32
+ dc = vim.serviceInstance.find_datacenter("datacenter1") or fail "datacenter not found"
33
+ @vm = dc.find_vm("test") or fail "VM not found"
34
+ end
35
+
36
+ def start
37
+ @vm.PowerOnVM_Task.wait_for_completion
38
+ end
39
+
40
+ def stop
41
+ @vm.PowerOffVM_Task.wait_for_completion
42
+ end
43
+
44
+ def suspend
45
+ @vm.SuspendVM_Task.wait_for_completion
46
+ end
47
+
48
+ def pause
49
+ raise "Unimplemented"
50
+ end
51
+
52
+ def resume
53
+ raise "Unimplemented"
54
+ end
55
+
56
+ def reset
57
+ @vm.ResetVM_Task.wait_for_completion
58
+ end
59
+
60
+ def create_snapshot(snapshot)
61
+ snapshot = filter_input(snapshot)
62
+ raise "Unimplemented"
63
+ end
64
+
65
+ def revert_snapshot(snapshot)
66
+ raise "Unimplemented"
67
+ # If we got here, the snapshot didn't exist
68
+ raise "Invalid Snapshot Name"
69
+ end
70
+
71
+ def delete_snapshot(snapshot, remove_children=false)
72
+ raise "Unimplemented"
73
+ # If we got here, the snapshot didn't exist
74
+ raise "Invalid Snapshot Name"
75
+ end
76
+
77
+ def delete_all_snapshots
78
+ raise "Unimplemented"
79
+ end
80
+
81
+ def run_command(command)
82
+ raise "Unimplemented"
83
+ end
84
+
85
+ def copy_from(from, to)
86
+ if @os == "linux"
87
+ scp_from(from, to)
88
+ else
89
+ raise "Unimplemented"
90
+ end
91
+ end
92
+
93
+ def copy_to(from, to)
94
+ if @os == "linux"
95
+ scp_to(from, to)
96
+ else
97
+ raise "Unimplemented"
98
+ end
99
+ end
100
+
101
+ def check_file_exists(file)
102
+ raise "Unimplemented"
103
+ end
104
+
105
+ def create_directory(directory)
106
+ raise "Unimplemented"
107
+ end
108
+
109
+ def cleanup
110
+ raise "Unimplemented"
111
+ end
112
+
113
+ def running?
114
+ raise "Unimplemented"
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+ end
@@ -0,0 +1,234 @@
1
+ require 'vm_driver'
2
+
3
+ ##
4
+ ## $Id$
5
+ ##
6
+
7
+ module Lab
8
+ module Drivers
9
+
10
+ class WorkstationDriver < VmDriver
11
+
12
+ def initialize(config)
13
+ super(config)
14
+
15
+ if !File.exist?(@location)
16
+ raise ArgumentError,"Couldn't find: #{@location}"
17
+ end
18
+ end
19
+
20
+ def start
21
+ system_command("vmrun -T ws start " + "\'#{@location}\' nogui")
22
+ end
23
+
24
+ def stop
25
+ system_command("vmrun -T ws stop " + "\'#{@location}\' nogui")
26
+ end
27
+
28
+ def suspend
29
+ system_command("vmrun -T ws suspend " + "\'#{@location}\' nogui")
30
+ end
31
+
32
+ def pause
33
+ system_command("vmrun -T ws pause " + "\'#{@location}\' nogui")
34
+ end
35
+
36
+ def reset
37
+ system_command("vmrun -T ws reset " + "\'#{@location}\' nogui")
38
+ end
39
+
40
+ def create_snapshot(snapshot)
41
+ snapshot = filter_input(snapshot)
42
+ system_command("vmrun -T ws snapshot " + "\'#{@location}\' \'#{snapshot}\' nogui")
43
+ end
44
+
45
+ def revert_snapshot(snapshot)
46
+ snapshot = filter_input(snapshot)
47
+ system_command("vmrun -T ws revertToSnapshot " + "\'#{@location}\' \'#{snapshot}\' nogui")
48
+ end
49
+
50
+ def delete_snapshot(snapshot)
51
+ snapshot = filter_input(snapshot)
52
+ system_command("vmrun -T ws deleteSnapshot " + "\'#{@location}\' \'#{snapshot}\' nogui" )
53
+ end
54
+
55
+ def run_command(command)
56
+
57
+ #
58
+ # Generate a script name
59
+ #
60
+ script_rand_name = rand(1000000)
61
+
62
+ #
63
+ # Configure paths for each OS - We really can't filter command, so we're gonna
64
+ # stick it in a script
65
+ #
66
+ if @os == "windows"
67
+ local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.bat"
68
+ remote_tempfile_path = "C:\\\\lab_script_#{script_rand_name}.bat"
69
+ remote_output_file = "C:\\\\lab_command_output_#{script_rand_name}"
70
+ remote_run_command = remote_tempfile_path
71
+ File.open(local_tempfile_path, 'w') {|f| f.write(command) }
72
+ else
73
+
74
+ local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh"
75
+ remote_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh"
76
+ remote_output_file = "/tmp/lab_command_output_#{script_rand_name}"
77
+ local_output_file = "/tmp/lab_command_output_#{script_rand_name}"
78
+
79
+ remote_run_command = remote_tempfile_path
80
+
81
+ File.open(local_tempfile_path, 'w') {|f| f.write("#!/bin/sh\n#{command}\n")}
82
+ end
83
+
84
+ if @tools
85
+
86
+ #puts "DEBUG: Running w/ tools"
87
+
88
+ #
89
+ # Copy our local tempfile to the guest
90
+ #
91
+ vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
92
+ "copyFileFromHostToGuest \'#{@location}\' \'#{local_tempfile_path}\'" +
93
+ " \'#{remote_tempfile_path}\'"
94
+ system_command(vmrunstr)
95
+
96
+ if @os == "linux"
97
+ #
98
+ # Now run the command directly on the guest (linux - call w/ /bin/sh)
99
+ #
100
+ vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
101
+ "runProgramInGuest \'#{@location}\' /bin/sh #{remote_tempfile_path} > #{remote_output_file}"
102
+ system_command(vmrunstr)
103
+ else
104
+ #
105
+ # Now run the command directly on the guest (windows)
106
+ #
107
+ vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
108
+ "runProgramInGuest \'#{@location}\' #{remote_tempfile_path} > #{remote_output_file}"
109
+ system_command(vmrunstr)
110
+ end
111
+
112
+ #
113
+ # Cleanup. Delete it on the guest
114
+ #
115
+ vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " +
116
+ "deleteFileInGuest \'#{@location}\' \'#{remote_tempfile_path}\'"
117
+ system_command(vmrunstr)
118
+
119
+ #
120
+ # Delete it locally
121
+ #
122
+ local_delete_command = "rm #{local_tempfile_path}"
123
+ system_command(local_delete_command)
124
+ else
125
+
126
+ #
127
+ # Use SCP / SSH
128
+ #
129
+
130
+ if @os == "linux"
131
+
132
+ #
133
+ # Copy it over
134
+ #
135
+ scp_to(local_tempfile_path, remote_tempfile_path)
136
+
137
+ #
138
+ # And ... execute it
139
+ #
140
+ ssh_exec("/bin/sh #{remote_tempfile_path} > #{remote_output_file}")
141
+
142
+ #
143
+ # Now copy the output back to us
144
+ #
145
+ scp_from(remote_output_file, local_output_file)
146
+
147
+ # Now, let's look at the output of the command
148
+ output_string = File.open(local_output_file,"r").read
149
+
150
+ #
151
+ # And clean up
152
+ #
153
+ ssh_exec("rm #{remote_output_file}")
154
+ ssh_exec("rm #{remote_tempfile_path}")
155
+
156
+ `rm #{local_output_file}`
157
+
158
+ else
159
+ raise "Hey, no tools, and windows? can't do nuttin for ya man."
160
+ end
161
+
162
+ end
163
+ output_string
164
+ end
165
+
166
+ def copy_from(from, to)
167
+ from = filter_input(from)
168
+ to = filter_input(to)
169
+ if @tools
170
+ vmrunstr = "vmrun -T ws -gu \'#{@vm_user}\' -gp \'#{@vm_pass}\' copyFileFromGuestToHost " +
171
+ "\'#{@location}\' \'#{from}\' \'#{to}\'"
172
+ else
173
+ scp_from(from, to)
174
+ end
175
+ system_command(vmrunstr)
176
+ end
177
+
178
+ def copy_to(from, to)
179
+ from = filter_input(from)
180
+ to = filter_input(to)
181
+ if @tools
182
+ vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} copyFileFromHostToGuest " +
183
+ "\'#{@location}\' \'#{from}\' \'#{to}\'"
184
+ system_command(vmrunstr)
185
+ else
186
+ scp_to(from, to)
187
+ end
188
+ end
189
+
190
+ def check_file_exists(file)
191
+ file = filter_input(file)
192
+ if @tools
193
+ vmrunstr = "vmrun -T ws -gu \'#{@vm_user}\' -gp \'#{@vm_pass}\' fileExistsInGuest " +
194
+ "\'#{@location}\' \'#{file}\'"
195
+ system_command(vmrunstr)
196
+ else
197
+ raise "Unsupported"
198
+ end
199
+ end
200
+
201
+ def create_directory(directory)
202
+ directory = filter_input(directory)
203
+ if @tools
204
+ vmrunstr = "vmrun -T ws -gu \'#{@vm_user}\' -gp \'#{@vm_pass}\' createDirectoryInGuest " +
205
+ " \'#{@location}\' \'#{directory}\' "
206
+ system_command(vmrunstr)
207
+ else
208
+ raise "Unsupported"
209
+ end
210
+ end
211
+
212
+ def cleanup
213
+
214
+ end
215
+
216
+ def running?
217
+ ## Get running Vms
218
+ running = `vmrun list`
219
+ running_array = running.split("\n")
220
+ running_array.shift
221
+
222
+ running_array.each do |vmx|
223
+ if vmx.to_s == @location.to_s
224
+ return true
225
+ end
226
+ end
227
+
228
+ return false
229
+ end
230
+
231
+ end
232
+
233
+ end
234
+ end