From 37821c95e9775b135111b75219b038c5077d88a0 Mon Sep 17 00:00:00 2001 From: Jonathan Cran Date: Tue, 3 Apr 2012 12:43:00 -0500 Subject: [PATCH] back to sanity. added a console and updated the test lab --- config/test_lab.yml | 61 ++++ lib/lab/controller/vsphere_controller.rb | 48 +-- lib/lab/driver/vsphere_driver.rb | 4 +- lib/lab/vm_controller.rb | 19 +- src/Gemfile | 4 - src/Rakefile | 1 - src/TODO | 15 - src/config/test_lab.yml | 11 - src/config/test_targets.yml | 21 -- src/lab.gemspec | 35 --- src/lib/lab.rb | 2 - src/lib/lab/controller/dynagen_controller.rb | 14 - src/lib/lab/controller/fog_controller.rb | 6 - .../lab/controller/remote_esxi_controller.rb | 62 ---- .../remote_workstation_controller.rb | 22 -- .../lab/controller/virtualbox_controller.rb | 25 -- src/lib/lab/controller/vsphere_controller.rb | 18 -- .../lab/controller/workstation_controller.rb | 17 -- .../controller/workstation_vixr_controller.rb | 19 -- src/lib/lab/controllers.rb | 9 - src/lib/lab/driver/dynagen_driver.rb | 47 --- src/lib/lab/driver/fog_driver.rb | 104 ------- src/lib/lab/driver/remote_esxi_driver.rb | 177 ----------- .../lab/driver/remote_workstation_driver.rb | 197 ------------- src/lib/lab/driver/virtualbox_driver.rb | 142 --------- src/lib/lab/driver/vm_driver.rb | 195 ------------- src/lib/lab/driver/vsphere_driver.rb | 120 -------- src/lib/lab/driver/workstation_driver.rb | 234 --------------- src/lib/lab/driver/workstation_vixr_driver.rb | 126 -------- src/lib/lab/drivers.rb | 9 - src/lib/lab/modifier/backtrack5_modifier.rb | 16 - src/lib/lab/modifier/dos_modifier.rb | 14 - src/lib/lab/modifier/test_modifier.rb | 16 - src/lib/lab/modifiers.rb | 3 - src/lib/lab/version.rb | 3 - src/lib/lab/vm.rb | 269 ----------------- src/lib/lab/vm_controller.rb | 275 ------------------ src/test/.gitkeep | 0 util/console.rb | 10 + 39 files changed, 90 insertions(+), 2280 deletions(-) delete mode 100644 src/Gemfile delete mode 100644 src/Rakefile delete mode 100644 src/TODO delete mode 100755 src/config/test_lab.yml delete mode 100755 src/config/test_targets.yml delete mode 100644 src/lab.gemspec delete mode 100644 src/lib/lab.rb delete mode 100644 src/lib/lab/controller/dynagen_controller.rb delete mode 100644 src/lib/lab/controller/fog_controller.rb delete mode 100644 src/lib/lab/controller/remote_esxi_controller.rb delete mode 100644 src/lib/lab/controller/remote_workstation_controller.rb delete mode 100644 src/lib/lab/controller/virtualbox_controller.rb delete mode 100644 src/lib/lab/controller/vsphere_controller.rb delete mode 100644 src/lib/lab/controller/workstation_controller.rb delete mode 100644 src/lib/lab/controller/workstation_vixr_controller.rb delete mode 100644 src/lib/lab/controllers.rb delete mode 100644 src/lib/lab/driver/dynagen_driver.rb delete mode 100644 src/lib/lab/driver/fog_driver.rb delete mode 100644 src/lib/lab/driver/remote_esxi_driver.rb delete mode 100644 src/lib/lab/driver/remote_workstation_driver.rb delete mode 100644 src/lib/lab/driver/virtualbox_driver.rb delete mode 100644 src/lib/lab/driver/vm_driver.rb delete mode 100644 src/lib/lab/driver/vsphere_driver.rb delete mode 100644 src/lib/lab/driver/workstation_driver.rb delete mode 100644 src/lib/lab/driver/workstation_vixr_driver.rb delete mode 100644 src/lib/lab/drivers.rb delete mode 100644 src/lib/lab/modifier/backtrack5_modifier.rb delete mode 100644 src/lib/lab/modifier/dos_modifier.rb delete mode 100644 src/lib/lab/modifier/test_modifier.rb delete mode 100644 src/lib/lab/modifiers.rb delete mode 100644 src/lib/lab/version.rb delete mode 100644 src/lib/lab/vm.rb delete mode 100644 src/lib/lab/vm_controller.rb delete mode 100644 src/test/.gitkeep create mode 100755 util/console.rb diff --git a/config/test_lab.yml b/config/test_lab.yml index 515331f..52e5f98 100755 --- a/config/test_lab.yml +++ b/config/test_lab.yml @@ -6,6 +6,67 @@ credentials: - user: root pass: toor + admin: true os: linux flavor: ubuntu arch: 64 + - vmid: backtrack_remote + driver: remote_workstation + user: root + host: vmhost + modifiers: + - Test + credentials: + - user: root + pass: toor + admin: true + os: linux + flavor: ubuntu + arch: 64 +### +# Windows XP SP3 - Browser Autopwn Target +### + - vmid: 222 + hostname: xp + description: Windows XP SP3 - Browser Autopwn Target + driver: remote_esxi + user: root + host: vmhost1 + type: target + arch: 32 + os: linux + credentials: + - user: msfadmin + pass: msfadmin + admin: true + tags: + - ie6 + - ie7 + - ie8 + - firefox + - java + - flash + - quicktime +### +# Windows 7 SP1 +### + - vmid: 1111 + hostname: win7 + description: Windows 7 SP1 - Browser Autopwn Target + driver: remote_esxi + user: root + host: vmhost1 + pass: whatever + type: target + arch: 32 + os: linux + credentials: + - user: msfadmin + pass: msfadmin + admin: true + tags: + - ie8 + - firefox + - java + - flash + - quicktime diff --git a/lib/lab/controller/vsphere_controller.rb b/lib/lab/controller/vsphere_controller.rb index 7b3ea31..9cb0714 100644 --- a/lib/lab/controller/vsphere_controller.rb +++ b/lib/lab/controller/vsphere_controller.rb @@ -3,58 +3,14 @@ module Lab module Controllers -module RemoteEsxiController - - # Note that 3.5 was different (vmware-vim-cmd) - VIM_CMD = 'vim-cmd'.freeze +module VsphereController def self.dir_list(basepath=nil) # Does this method really even make sense for esxi? - return "Unsupported :(" + return "Unimplemented" end def self.running_list(user, host) - user.gsub!(/(\W)*/, '') - host.gsub!(/(\W)*/, '') - - # first get all registered vms - registered_vms = self.get_vms(user, host) || [] - running_vms = [] - - # now let's see which ones are running - # TODO: this is ghetto, would be better not to connect repeatedly - registered_vms.each do |vm| - remote_cmd = "ssh #{user}@#{host} \"#{VIM_CMD} vmsvc/power.getstate #{vm[:id]}\"" - raw = `#{remote_cmd}` - running_vms << vm if raw =~ /Powered on/ - end - - return running_vms - end - -private - - def self.get_vms(user, host) - user.gsub!(/(\W)*/, '') - host.gsub!(/(\W)*/, '') - - vms = [] # array of VM hashes - remote_cmd = "ssh #{user}@#{host} \"#{VIM_CMD} vmsvc/getallvms | grep ^[0-9] | sed 's/[[:blank:]]\\{3,\\}/ /g'\"" - raw = `#{remote_cmd}`.split("\n") - - raw.each do |line| - # So effing ghetto - id_and_name = line.split('[datastore').first - id = id_and_name.split(' ').first - - # TODO - there's surely a better way to do this. - name_array = id_and_name.split(' ') - name_array.shift - name = name_array.join(' ') - vms << {:id => id, :name => name} - end - - return vms end end diff --git a/lib/lab/driver/vsphere_driver.rb b/lib/lab/driver/vsphere_driver.rb index 89c066d..445c036 100644 --- a/lib/lab/driver/vsphere_driver.rb +++ b/lib/lab/driver/vsphere_driver.rb @@ -15,7 +15,7 @@ class VsphereDriver < VmDriver def initialize(config) unless config['user'] then raise ArgumentError, "Must provide a username" end unless config['host'] then raise ArgumentError, "Must provide a hostname" end - unless config[''] then raise ArgumentError, "Must provide a password" end + unless config['pass'] then raise ArgumentError, "Must provide a password" end super(config) @user = filter_command(config['user']) @@ -28,7 +28,7 @@ def initialize(config) raise "WARNING: Library rbvmomi not found. Could not create driver!" end - vim = RbVmomi::VIM.connect host: @host, user: @user, password: @pass + vim = RbVmomi::VIM.connect host: @host, user: @user, password: @pass, insecure: true dc = vim.serviceInstance.find_datacenter("datacenter1") or fail "datacenter not found" @vm = dc.find_vm("test") or fail "VM not found" end diff --git a/lib/lab/vm_controller.rb b/lib/lab/vm_controller.rb index 5a66120..f5fbe6c 100644 --- a/lib/lab/vm_controller.rb +++ b/lib/lab/vm_controller.rb @@ -35,7 +35,7 @@ class VmController include Lab::Controllers::FogController include Lab::Controllers::DynagenController include Lab::Controllers::RemoteEsxiController - include Lab::Controllers::VsphereDriver + include Lab::Controllers::VsphereController #include Lab::Controllers::QemuController #include Lab::Controllers::QemudoController def initialize (labdef=nil) @@ -62,15 +62,19 @@ def [](x) def find_by_vmid(search) @vms.each do |vm| - return vm if vm.hostname.to_s.downcase == search.to_s.downcase + return vm if vm.hostname == search end - return nil + nil + end + + def find_by_hostname(search) + self.find_by_vmid search end def find_by_tag(search) @vms.each do |vm| vm.tags.each do |tag| - return vm if tag.downcase == search.to_s.downcase + return vm if tag == search end end return nil @@ -121,6 +125,13 @@ def includes_vmid?(vmid) false end + def includes_hostname?(hostname) + @vms.each do |vm| + return true if (vm.hostname == hostname) + end + false + end + # # Build a vm lab from a directory of files. Really only useful for file-based # vm hosts. (vmware workstation) diff --git a/src/Gemfile b/src/Gemfile deleted file mode 100644 index 78a1014..0000000 --- a/src/Gemfile +++ /dev/null @@ -1,4 +0,0 @@ -source "http://rubygems.org" - -# Specify your gem's dependencies in lab.gemspec -gemspec diff --git a/src/Rakefile b/src/Rakefile deleted file mode 100644 index 2995527..0000000 --- a/src/Rakefile +++ /dev/null @@ -1 +0,0 @@ -require "bundler/gem_tasks" diff --git a/src/TODO b/src/TODO deleted file mode 100644 index 6652587..0000000 --- a/src/TODO +++ /dev/null @@ -1,15 +0,0 @@ -This is a list of basic priorities for the lab code... - -* Implement more technologies - - a) finish amazon ec2 (via fog) - b) qemu - c) qemudo - d) kvm - e) other cloud technologies (newservers, slicehost/rackspace,etc) - -* Implement a cloning function on each controller - -* Support Windows as a host platform. Currently all the code assumes a linux host is running it. The same applies for the remote_* drivers -- they've not been tested on windows. - -* Consolidate the remote_system_command code & provide a filter. Create an unsafe_system_command and unsafe_remote_system_command function call for when we control the entire string. diff --git a/src/config/test_lab.yml b/src/config/test_lab.yml deleted file mode 100755 index 515331f..0000000 --- a/src/config/test_lab.yml +++ /dev/null @@ -1,11 +0,0 @@ - - vmid: backtrack - driver: workstation - location: /opt/vm/backtrack5/Backtrack5x64.vmx - modifiers: - - Test - credentials: - - user: root - pass: toor - os: linux - flavor: ubuntu - arch: 64 diff --git a/src/config/test_targets.yml b/src/config/test_targets.yml deleted file mode 100755 index 85dde25..0000000 --- a/src/config/test_targets.yml +++ /dev/null @@ -1,21 +0,0 @@ - - vmid: metasploitable - driver: workstation - location: /opt/vm/lab/user/Metasploitable/Metasploitable.vmx - tools: false - credentials: - - user: msfadmin - pass: msfadmin - - vmid: windows2000_target - driver: workstation - location: /opt/vm/lab/vuln/msf_Win2000SP4/Windows 2000 AS.vmx - tools: true - credentials: - - vmid: windowsxp_target - driver: remote_workstation - host: vmhost - user: root - location: /opt/vm/lab/vuln/msf_WinXPSP1/Windows XP Professional.vmx - tools: true - credentials: - - user: administrator - pass: administrator diff --git a/src/lab.gemspec b/src/lab.gemspec deleted file mode 100644 index 3816f83..0000000 --- a/src/lab.gemspec +++ /dev/null @@ -1,35 +0,0 @@ -# -*- encoding: utf-8 -*- -lib = File.expand_path('../lib/', __FILE__) -$:.unshift lib unless $:.include?(lib) -require 'lab/version' - -Gem::Specification.new do |s| - s.name = "lab" - s.version = Lab::VERSION - s.authors = ["Jonathan Cran"] - s.email = ["jcran@rapid7.com"] - s.homepage = "http://www.github.com/rapid7/lab/wiki" - s.summary = %q{Manage VMs like a boss} - s.description = %q{Start/Stop/Revert and do other cool stuff w/ Vmware, Virtualbox, and ESXi vms. This gem wraps common CLI utilities and other gems to create a common inteface for vms. } - - s.rubyforge_project = "lab" - - s.files = `git ls-files`.split("\n") - s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") - s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } - s.require_paths = ["lib"] - - # specify any dependencies here; for example: - # s.add_development_dependency "rspec" - - # ?? - s.add_runtime_dependency "nokogiri" - - # Multiple things - fallback execute / copy - s.add_runtime_dependency "net-ssh" - s.add_runtime_dependency "net-scp" - - # Vmware ESX driver - s.add_runtime_dependency "rbvmomi" - -end diff --git a/src/lib/lab.rb b/src/lib/lab.rb deleted file mode 100644 index 60c887d..0000000 --- a/src/lib/lab.rb +++ /dev/null @@ -1,2 +0,0 @@ -require 'lab/vm_controller' -require 'lab/version' diff --git a/src/lib/lab/controller/dynagen_controller.rb b/src/lib/lab/controller/dynagen_controller.rb deleted file mode 100644 index 515d848..0000000 --- a/src/lib/lab/controller/dynagen_controller.rb +++ /dev/null @@ -1,14 +0,0 @@ -module Lab -module Controllers -module DynagenController - - def self.running_list - raise "Unsupported" - end - - def self.dir_list(basepath=nil) - raise "Unsupported" - end -end -end -end diff --git a/src/lib/lab/controller/fog_controller.rb b/src/lib/lab/controller/fog_controller.rb deleted file mode 100644 index 9d671af..0000000 --- a/src/lib/lab/controller/fog_controller.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Lab -module Controllers -module FogController -end -end -end diff --git a/src/lib/lab/controller/remote_esxi_controller.rb b/src/lib/lab/controller/remote_esxi_controller.rb deleted file mode 100644 index 37df58d..0000000 --- a/src/lib/lab/controller/remote_esxi_controller.rb +++ /dev/null @@ -1,62 +0,0 @@ -# This controller was built against: -# VMware ESX Host Agent 4.1.0 build-348481 - -module Lab -module Controllers -module RemoteEsxiController - - # Note that 3.5 was different (vmware-vim-cmd) - VIM_CMD = 'vim-cmd'.freeze - - def self.dir_list(basepath=nil) - # Does this method really even make sense for esxi? - return "Unsupported :(" - end - - def self.running_list(user, host) - user.gsub!(/(\W)*/, '') - host.gsub!(/(\W)*/, '') - - # first get all registered vms - registered_vms = self.get_vms(user, host) || [] - running_vms = [] - - # now let's see which ones are running - # TODO: this is ghetto, would be better not to connect repeatedly - registered_vms.each do |vm| - remote_cmd = "ssh #{user}@#{host} \"#{VIM_CMD} vmsvc/power.getstate #{vm[:id]}\"" - raw = `#{remote_cmd}` - running_vms << vm if raw =~ /Powered on/ - end - - return running_vms - end - -private - - def self.get_vms(user, host) - user.gsub!(/(\W)*/, '') - host.gsub!(/(\W)*/, '') - - vms = [] # array of VM hashes - remote_cmd = "ssh #{user}@#{host} \"#{VIM_CMD} vmsvc/getallvms | grep ^[0-9] | sed 's/[[:blank:]]\\{3,\\}/ /g'\"" - raw = `#{remote_cmd}`.split("\n") - - raw.each do |line| - # So effing ghetto - id_and_name = line.split('[datastore').first - id = id_and_name.split(' ').first - - ## TODO - there's surely a better way to do this. - name_array = id_and_name.split(' ') - name_array.shift - name = name_array.join(' ') - vms << {:id => id, :name => name} - end - - return vms - end - -end -end -end diff --git a/src/lib/lab/controller/remote_workstation_controller.rb b/src/lib/lab/controller/remote_workstation_controller.rb deleted file mode 100644 index 6bc3ad6..0000000 --- a/src/lib/lab/controller/remote_workstation_controller.rb +++ /dev/null @@ -1,22 +0,0 @@ -module Lab -module Controllers -module RemoteWorkstationController - - def self.running_list(user, host) - user.gsub!(/(\W)*/, '') - host.gsub!(/(\W)*/, '') - - remote_cmd = "ssh #{user}@#{host} \"vmrun list nogui\"" - vm_list = `#{remote_cmd}`.split("\n") - vm_list.shift - - return vm_list - end - - def self.dir_list(basepath=nil) - vm_list = Find.find(basepath).select { |f| f =~ /\.vmx$/ } - return vm_list - end -end -end -end diff --git a/src/lib/lab/controller/virtualbox_controller.rb b/src/lib/lab/controller/virtualbox_controller.rb deleted file mode 100644 index 218b927..0000000 --- a/src/lib/lab/controller/virtualbox_controller.rb +++ /dev/null @@ -1,25 +0,0 @@ -module Lab -module Controllers -module VirtualBoxController - - def self.running_list - vm_names_and_uuids = `VBoxManage list runningvms` - return vm_names_and_uuids.scan(/\"(.*)\" {.*}/).flatten - end - - def self.config_list - vm_names_and_uuids = `VBoxManage list vms` - return vm_names_and_uuids.scan(/\"(.*)\" {.*}/).flatten - end - - def self.config_list_uuid - vm_names_and_uuids = `VBoxManage list vms` - return vm_names_and_uuids.scan(/\".*\" {(.*)}/).flatten - end - - def self.dir_list(basepath=nil) - vm_list = Find.find(basepath).select { |f| f =~ /\.xml$/ } - end -end -end -end diff --git a/src/lib/lab/controller/vsphere_controller.rb b/src/lib/lab/controller/vsphere_controller.rb deleted file mode 100644 index 385c23a..0000000 --- a/src/lib/lab/controller/vsphere_controller.rb +++ /dev/null @@ -1,18 +0,0 @@ -# This controller was built against: -# VMware ESX Host Agent 4.1.0 build-348481 - -module Lab -module Controllers -module VsphereController - - def self.dir_list(basepath=nil) - return "Unimplemented" - end - - def self.running_list(user, host) - return "Unimplemented" - end - -end -end -end diff --git a/src/lib/lab/controller/workstation_controller.rb b/src/lib/lab/controller/workstation_controller.rb deleted file mode 100644 index ef2a3db..0000000 --- a/src/lib/lab/controller/workstation_controller.rb +++ /dev/null @@ -1,17 +0,0 @@ -module Lab -module Controllers -module WorkstationController - - def self.running_list - vm_list = `vmrun list`.split("\n") - vm_list.shift - return vm_list - end - - def self.dir_list(basepath=nil) - vm_list = Find.find(basepath).select { |f| f =~ /\.vmx$/ } - return vm_list - end -end -end -end diff --git a/src/lib/lab/controller/workstation_vixr_controller.rb b/src/lib/lab/controller/workstation_vixr_controller.rb deleted file mode 100644 index ff2bac5..0000000 --- a/src/lib/lab/controller/workstation_vixr_controller.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Lab -module Controllers -module WorkstationVixrController - - def self.running_list - vm_list = `vmrun list`.split("\n") - vm_list.shift - - return vm_list - end - - def self.dir_list(basepath=nil) - vm_list = Find.find(basepath).select { |f| f =~ /\.vmx$/ } - - return vm_list - end -end -end -end diff --git a/src/lib/lab/controllers.rb b/src/lib/lab/controllers.rb deleted file mode 100644 index 541664d..0000000 --- a/src/lib/lab/controllers.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'controller/workstation_controller' -require 'controller/virtualbox_controller' -require 'controller/fog_controller' -require 'controller/dynagen_controller' -require 'controller/remote_workstation_controller' -require 'controller/remote_esxi_controller' -require 'controller/vsphere_controller' -#require 'controller/qemu_controller' -#require 'controller/qemudo_controller' diff --git a/src/lib/lab/driver/dynagen_driver.rb b/src/lib/lab/driver/dynagen_driver.rb deleted file mode 100644 index ef740b2..0000000 --- a/src/lib/lab/driver/dynagen_driver.rb +++ /dev/null @@ -1,47 +0,0 @@ -require 'vm_driver' - -# -# $Id$ -# - -# -# To use this driver, you have to have a lab which is preconfigured. The best / easiest -# way i've found to to set up a lab is GNS3 -# - -module Lab -module Drivers - class DynagenDriver < VmDriver - def initialize(config,dynagen_config) - super(config) - @running = false - @dynagen_platform = filter_command(dynagen_config['dynagen_platform']) - end - - def start - # TODO - write the location-file to a temp-file - # and set the autostart property - - ## start background dynamips process - system_command("dynamips -H #{@dynagen_platform} &") - system_command("dynagen #{@location}") - @running = true - end - - def stop - system_command("killall dynagen") - @running = false - end - - def cleanup - `killall dynagen` - `killall dynamips` - @running = false - end - - def running? - return @running - end - end -end -end diff --git a/src/lib/lab/driver/fog_driver.rb b/src/lib/lab/driver/fog_driver.rb deleted file mode 100644 index 5a25207..0000000 --- a/src/lib/lab/driver/fog_driver.rb +++ /dev/null @@ -1,104 +0,0 @@ -require 'vm_driver' - -## -## $Id$ -## - -module Lab -module Drivers -class FogDriver < VmDriver - - def initialize(config,fog_config) - - super(config) - @fog_config = fog_config - - # Soft dependency - begin - require 'fog' - rescue LoadError - raise "WARNING: Library fog not found. Could not create driver" - end - - if @fog_config['fog_type'] == "ec2" - - # AWS / EC2 Base Credential Configuration - @aws_cert_file = IO.read(fog_config['fog_aws_cert_file']).chomp if fog_config['fog_aws_cert_file'] - @aws_private_key_file = IO.read(fog_config['fog_aws_private_key_file']).chomp if fog_config['fog_aws_private_key_file'] - @ec2_access_key_file = IO.read(fog_config['fog_ec2_access_key_file']).chomp if fog_config['fog_ec2_access_key_file'] - @ec2_secret_access_key_file = IO.read(fog_config['fog_ec2_secret_access_key_file']).chomp if fog_config['fog_ec2_secret_access_key_file'] - - # Instance Keys - @ec2_instance_public_key_file = IO.read(fog_config['fog_ec2_instance_public_key_file']).chomp if fog_config['fog_ec2_instance_public_key_file'] - @ec2_instance_private_key_file = IO.read(fog_config['fog_ec2_instance_private_key_file']).chomp if fog_config['fog_ec2_instance_private_key_file'] - - # Instance Details - @ec2_base_ami = fog_config['fog_ec2_base_ami'] - @ec2_flavor = fog_config['fog_ec2_flavor'] - @ec2_user = fog_config['fog_ec2_user'] - @ec2_region = fog_config['fog_ec2_region'] - - # Set up a connection - @compute = Fog::Compute.new( - :provider => "Aws", - :aws_access_key_id => @aws_access_key_file, - :aws_secret_access_key => @aws_secret_access_key_file ) - else - raise "Unsupported fog type" - end - end - - def start - ec2_settings = { - :image_id => @ec2_base_ami, - :flavor_id => @ec2_flavor, - :public_key_path => @ec2_instance_public_key_file, - :private_key_path => @ec2_instance_private_key_file, - :username => @ec2_user} - begin - @fog_server = @compute.servers.bootstrap(ec2_settings) - rescue Fog::Compute::AWS::Error => e - raise "Couldn't authenticate to AWS - did you place keys in the creds/ directory?" - exit - end - end - - def stop - @fog_server.destroy - end - - def suspend - raise "unimplemented" - end - - def pause - raise "unimplemented" - end - - def reset - raise "unimplemented" - end - - def create_snapshot(snapshot) - raise "unimplemented" - end - - def revert_snapshot(snapshot) - raise "unimplemented" - end - - def delete_snapshot(snapshot) - raise "unimplemented" - end - - def cleanup - @fog_server.destroy - end - - def running? - return true #TODO - end - -end -end -end diff --git a/src/lib/lab/driver/remote_esxi_driver.rb b/src/lib/lab/driver/remote_esxi_driver.rb deleted file mode 100644 index 89934cb..0000000 --- a/src/lib/lab/driver/remote_esxi_driver.rb +++ /dev/null @@ -1,177 +0,0 @@ -require 'vm_driver' - -## -## $Id$ -## - -# This driver was built against: -# VMware ESXi Host Agent 4.1.0 build-348481 - -module Lab -module Drivers - -class RemoteEsxiDriver < VmDriver - - def initialize(config) - unless config['user'] then raise ArgumentError, "Must provide a username" end - unless config['host'] then raise ArgumentError, "Must provide a hostname" end - - super(config) - - @user = filter_command(config['user']) - @host = filter_command(config['host']) - @port = config['port'] - end - - def start - remote_system_command("vim-cmd vmsvc/power.on #{@vmid}") - end - - def stop - remote_system_command("vim-cmd vmsvc/power.off #{@vmid}") - end - - def suspend - remote_system_command("vim-cmd vmsvc/power.suspend #{@vmid}") - end - - def pause - remote_system_command("vim-cmd vmsvc/power.suspend #{@vmid}") - end - - def resume - remote_system_command("vim-cmd vmsvc/power.suspendResume #{@vmid}") - end - - def reset - remote_system_command("vim-cmd vmsvc/power.reset #{@vmid}") - end - - def create_snapshot(snapshot) - snapshot = filter_input(snapshot) - - remote_system_command("vim-cmd vmsvc/snapshot.create #{@vmid} #{snapshot} \'lab created snapshot\' 1 true") - end - - def revert_snapshot(snapshot) - - snapshots = get_snapshots - - # Look through our snapshot list, choose the right one based on display_name - snapshots.each do |snapshot_obj| - - #puts "DEBUG: checking #{snapshot_obj}" - - if snapshot_obj[:display_name].downcase == snapshot.downcase - snapshot_identifier = snapshot_obj[:name].join(" ") - - #puts "DEBUG: I would revert to #{snapshot_obj}" - remote_system_command("vim-cmd vmsvc/snapshot.revert #{@vmid} 0 #{snapshot_identifier}") - return true - end - end - - # If we got here, the snapshot didn't exist - raise "Invalid Snapshot Name" - end - - def delete_snapshot(snapshot, remove_children=false) - snapshots = get_snapshots - - # Look through our snapshot list, choose the right one based on display_name - snapshots.each do |snapshot_obj| - - #puts "DEBUG: checking #{snapshot_obj}" - - if snapshot_obj[:display_name].downcase == snapshot.downcase - snapshot_identifier = snapshot_obj[:name].join(" ") - remote_system_command("vim-cmd vmsvc/snapshot.remove #{@vmid} #{remove_children} #{snapshot_identifier}") - return true - end - end - - # If we got here, the snapshot didn't exist - raise "Invalid Snapshot Name" - end - - def delete_all_snapshots - remote_system_command("vim-cmd vmsvc/snapshot.removeall #{@vmid}") - end - - def run_command(command) - raise "Not Implemented" - end - - def copy_from(from, to) - if @os == "linux" - scp_from(from, to) - else - raise "Unimplemented" - end - end - - def copy_to(from, to) - if @os == "linux" - scp_to(from, to) - else - raise "Unimplemented" - end - end - - def check_file_exists(file) - raise "Not Implemented" - end - - def create_directory(directory) - raise "Not Implemented" - end - - def cleanup - - end - - def running? - power_status_string = `ssh #{@user}@#{@host} \"vim-cmd vmsvc/power.getstate #{@vmid}\"` - return true if power_status_string =~ /Powered on/ - false - end - - def get_snapshots - # Command take the format: - # vmware-vim-cmd vmsvc/snapshot.revert [vmid: int] [snapshotlevel: int] [snapshotindex: int] - output = `ssh #{@user}@#{@host} \"vim-cmd vmsvc/snapshot.get #{@vmid}\"` - - # this keeps track of the snapshots, takes the form: - #[ {:name => [0,0], :display_name => "String containing the snapshotname}, - # {:name => [0,1], :display_name => "String containing the snapshotname}, ] - # ... - snapshots = [] - - # Use these to keep track of the parsing... - current_tree = -1 - current_num = 0 - count = 0 - - # Do the parsing & stick the snapshots in the snapshots array - output_lines = output.split("\n") - output_lines.each do |line| - if line.include?("|") # this is a new snapshot - if line.include?("ROOT") # it's a root - current_num = 0 - current_tree = current_tree + 1 # new tree - snapshots << { :name => [current_num, current_tree], :display_name => output_lines[count+1].split(":").last.strip } - else - current_num = current_num + 1 # new snapshot in current tree - snapshots << { :name => [current_num, current_tree], :display_name => output_lines[count+1].split(":").last.strip } - end - end - count = count+1 - end - - snapshots - end - -end - -end -end diff --git a/src/lib/lab/driver/remote_workstation_driver.rb b/src/lib/lab/driver/remote_workstation_driver.rb deleted file mode 100644 index 9c676ae..0000000 --- a/src/lib/lab/driver/remote_workstation_driver.rb +++ /dev/null @@ -1,197 +0,0 @@ -require 'vm_driver' - -## -## $Id$ -## - -module Lab -module Drivers - -class RemoteWorkstationDriver < VmDriver - - attr_accessor :location # among other things - - def initialize(config) - - unless config['user'] then raise ArgumentError, "Must provide a username" end - unless config['host'] then raise ArgumentError, "Must provide a hostname" end - - super(config) - - @user = filter_command(config['user']) - @host = filter_command(config['host']) - end - - def start - remote_system_command("vmrun -T ws start \'#{@location}\' nogui") - end - - def stop - remote_system_command("vmrun -T ws stop \'#{@location}\' nogui") - end - - def suspend - remote_system_command("vmrun -T ws suspend \'#{@location}\' nogui") - end - - def pause - remote_system_command("vmrun -T ws pause \'#{@location}\' nogui") - end - - def reset - remote_system_command("vmrun -T ws reset \'#{@location}\' nogui") - end - - def create_snapshot(snapshot) - snapshot = filter_input(snapshot) - remote_system_command("vmrun -T ws snapshot \'#{@location}\' #{snapshot} nogui") - end - - def revert_snapshot(snapshot) - snapshot = filter_input(snapshot) - remote_system_command("vmrun -T ws revertToSnapshot \'#{@location}\' #{snapshot} nogui") - end - - def delete_snapshot(snapshot) - snapshot = filter_input(snapshot) - remote_system_command("vmrun -T ws deleteSnapshot \'#{@location}\' #{snapshot} nogui" ) - end - - def run_command(command) - # generate local & remote script paths - script_rand_name = rand(10000) - - if @os == "windows" - local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.bat" - remote_tempfile_path = "C:\\\\lab_script_#{script_rand_name}.bat" - remote_run_command = remote_tempfile_path - else - local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh" - remote_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh" - remote_run_command = "/bin/sh #{remote_tempfile_path}" - end - - # write out our script locally - File.open(local_tempfile_path, 'w') {|f| f.write(command) } - - # we really can't filter command, so we're gonna stick it in a script - if @tools - # copy it to the vm host - this is because we're a remote driver - remote_copy_command = "scp #{local_tempfile_path} #{@user}@#{@host}:#{local_tempfile_path}" - system_command(remote_copy_command) - - # we have it on the vm host, copy it to the vm guest - vmrunstr = "ssh #{@user}@#{@host} \"vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " + - "copyFileFromHostToGuest \'#{@location}\' \'#{local_tempfile_path}\' " + - "\'#{remote_tempfile_path}\' nogui\"" - system_command(vmrunstr) - - # now run it on the guest - vmrunstr = "ssh #{@user}@#{@host} \"vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " + - "runProgramInGuest \'#{@location}\' -noWait -activeWindow \'#{remote_run_command}\'" - system_command(vmrunstr) - - ## CLEANUP - # delete it on the guest - vmrunstr = "ssh #{@user}@#{@host} \"vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " + - "deleteFileInGuest \'#{@location}\' \'#{remote_tempfile_path}\'" - system_command(vmrunstr) - - # and delete it on the vm host - vmhost_delete_command = "ssh #{@user}@#{@host} rm #{local_tempfile_path}" - system_command(vmhost_delete_command) - - # delete it locally - local_delete_command = "rm #{local_tempfile_path}" - system_command(local_delete_command) - else - # since we can't copy easily w/o tools, let's just run it directly :/ - if @os == "linux" - scp_to(local_tempfile_path, remote_tempfile_path) - ssh_exec(remote_run_command) - ssh_exec("rm #{remote_tempfile_path}") - else - raise "Not Implemented - Install VmWare Tools" - end - end - end - - def copy_from(from, to) - from = filter_input(from) - to = filter_input(to) - - # copy it to the vm host - this is because we're a remote driver - remote_copy_command = "scp #{from} #{@user}@#{@host}:#{from}" - system_command(remote_copy_command) - - if @tools - remote_system_command("ssh #{@user}@#{@host} \"vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " + - "copyFileFromGuestToHost \'#{@location}\' \'#{from}\' \'#{to}\' nogui") - else - scp_from(to,from) - end - end - - def copy_to(from, to) - - from = filter_input(from) - to = filter_input(to) - - # copy it to the vm host - this is because we're a remote driver - remote_copy_command = "scp #{from} #{@user}@#{@host}:#{from}" - system_command(remote_copy_command) - - if @tools - remote_system_command("vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " + - "copyFileFromHostToGuest \'#{@location}\' \'#{from}\' \'#{to}\' nogui") - else - scp_to(from,to) - end - end - - def check_file_exists(file) - - if @tools - file = filter_input(file) - remote_system_command("vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " + - "fileExistsInGuest \'#{@location}\' \'{file}\' nogui") - else - raise "Not Implemented - Install VmWare Tools" - end - end - - def create_directory(directory) - directory = filter_input(directory) - - if @tools - emote_system_command("ssh #{@user}@#{@host} vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " + - "createDirectoryInGuest \'#{@location}\' \'#{directory}\' nogui") - system_command(vmrunstr) - else - raise "Not Implemented - Install VmWare Tools" - end - end - - def cleanup - - end - - def running? - ## Get running VMs - running = `ssh #{@user}@#{@host} \"vmrun list nogui\"` - running_array = running.split("\n") - running_array.shift - - running_array.each do |vmx| - if vmx.to_s == @location.to_s - return true - end - end - - false - end - -end - -end -end diff --git a/src/lib/lab/driver/virtualbox_driver.rb b/src/lib/lab/driver/virtualbox_driver.rb deleted file mode 100644 index 6deb063..0000000 --- a/src/lib/lab/driver/virtualbox_driver.rb +++ /dev/null @@ -1,142 +0,0 @@ -require 'vm_driver' -require 'nokogiri' - -## -## $Id$ -## -module Lab -module Drivers - class VirtualBoxDriver < VmDriver - - attr_accessor :location - - def initialize(config) - - super(config) - - ## Check to see if we already know this vm, if not, go on location - vmid_list = ::Lab::Controllers::VirtualBoxController::config_list - unless vmid_list.include? @vmid - raise "Error, no such vm: #{@vmid}" unless @location - - if !File.exist?(@location) - raise ArgumentError,"Error, no vm at: #{@location}" - end - - # Registering @location - @vmid = register_and_return_vmid - end - - vmInfo = `VBoxManage showvminfo \"#{@vmid}\" --machinereadable` - @location = vmInfo.scan(/CfgFile=\"(.*?)\"/).flatten[0].to_s - - if !File.exist?(@location) - raise ArgumentError,"Couldn't find: " + @location - end - - end - - def register_and_return_vmid - - xml = Nokogiri::XML(File.new(@location)) - vmid = xml.root.xpath("//Machine[@name]") - - ## only register if we don't already know the vmid - if !::Lab::Controllers::VirtualBoxController::config_list.include? vmid - system_command("VBoxManage registervm \"#{@location}\"") - end - - return vmid - - end - - def unregister - system_command("VBoxManage unregistervm \"#{@vmid}\"") - end - - def start - system_command("VBoxManage startvm \"#{@vmid}\"") - end - - def stop - system_command("VBoxManage controlvm \"#{@vmid}\" poweroff") - end - - def suspend - system_command("VBoxManage controlvm \"#{@vmid}\" savestate") - end - - def pause - system_command("VBoxManage controlvm \"#{@vmid}\" pause") - end - - def reset - system_command("VBoxManage controlvm \"#{@vmid}\" reset") - end - - def create_snapshot(snapshot) - snapshot = filter_input(snapshot) - system_command("VBoxManage snapshot \"#{@vmid}\" take #{snapshot}") - end - - def revert_snapshot(snapshot) - snapshot = filter_input(snapshot) - system_command("VBoxManage snapshot \"#{@vmid}\" restore #{snapshot}") - end - - def delete_snapshot(snapshot) - snapshot = filter_input(snapshot) - system_command("VBoxManage snapshot \"#{@vmid}\" delete #{snapshot}") - end - - def run_command(command, arguments=nil) - command = filter_input(command) - arguments = filter_input(arguments) - - command = "VBoxManage guestcontrol exec \"#{@vmid}\" \"#{command}\" --username \"#{@vm_user}\"" + - " --password \"#{@vm_pass}\" --arguments \"#{arguments}\"" - system_command(command) - end - - def copy_from(from, to) - from = filter_input(from) - to = filter_input(to) - - raise "Not supported by Virtual Box" - end - - def copy_to(from, to) - from = filter_input(from) - to = filter_input(to) - - command = "VBoxManage guestcontrol copyto \"#{@vmid}\" \"#{from}\" \"#{to}\" " + - "--username \"#{@vm_user}\" --password \"#{@vm_pass}\"" - system_command(command) - end - - def check_file_exists(file) - file = filter_input(file) - - raise "Not supported by Virtual Box" - end - - def create_directory(directory) - directory = filter_input(directory) - - command = "VBoxManage guestcontrol createdir \"#{@vmid}\" \"#{directory}\" " + - "--username \"#{@vm_user}\" --password \"#{@vm_pass}\"" - system_command(command) - end - - def cleanup - - end - - def running? - ## Get running Vms - ::Lab::Controllers::VirtualBoxController::running_list.include? @vmid - end - - end -end -end diff --git a/src/lib/lab/driver/vm_driver.rb b/src/lib/lab/driver/vm_driver.rb deleted file mode 100644 index 4c82702..0000000 --- a/src/lib/lab/driver/vm_driver.rb +++ /dev/null @@ -1,195 +0,0 @@ -## -## $Id$ -## - -# -# !!WARNING!! - All drivers are expected to filter input before running -# anything based on it. This is particularly important in the case -# of the drivers which wrap a command line to provide functionality. -# - -module Lab -module Drivers -class VmDriver - - attr_accessor :vmid - attr_accessor :location - attr_accessor :os - attr_accessor :tools - attr_accessor :credentials - - def initialize(config) - - @vmid = filter_command(config["vmid"].to_s) - @location = filter_command(config["location"]) - @credentials = config["credentials"] || [] - @tools = filter_input(config["tools"]) - @arch = filter_input(config["arch"]) - @os = filter_input(config["os"]) - @hostname = filter_input(config["hostname"]) || filter_input(config["vmid"].to_s) - - # Currently only implemented for the first set - if @credentials.count > 0 - @vm_user = filter_input(@credentials[0]['user']) - @vm_pass = filter_input(@credentials[0]['pass']) - @vm_keyfile = filter_input(@credentials[0]['keyfile']) - end - end - - ## This interface must be implemented in a child driver class - ## ######################################################### - - def register - raise "Command not Implemented" - end - - def unregister - raise "Command not Implemented" - end - - def start - raise "Command not Implemented" - end - - def stop - raise "Command not Implemented" - end - - def suspend - raise "Command not Implemented" - end - - def pause - raise "Command not Implemented" - end - - def resume - raise "Command not Implemented" - end - - def reset - raise "Command not Implemented" - end - - def create_snapshot(snapshot) - raise "Command not Implemented" - end - - def revert_snapshot(snapshot) - raise "Command not Implemented" - end - - def delete_snapshot(snapshot) - raise "Command not Implemented" - end - - def run_command(command) - raise "Command not Implemented" - end - - def copy_from(from, to) - raise "Command not Implemented" - end - - def copy_to(from, to) - raise "Command not Implemented" - end - - def check_file_exists(file) - raise "Command not Implemented" - end - - def create_directory(directory) - raise "Command not Implemented" - end - - def cleanup - raise "Command not Implemented" - end - - ## End Interface - ## ######################################################### - -private - - # The only reason we don't filter here is because we need - # the ability to still run clean (controlled entirely by us) - # command lines. - def system_command(command) - puts "DEBUG: system command #{command}" - system(command) - end - - def remote_system_command(command) - puts "DEBUG: remote system command #{command} running with user #{@user}@#{@host}" - system_command("ssh #{@user}@#{@host} \"#{command}\"") - end - - def scp_to(local,remote) - if @vm_keyfile - #puts "DEBUG: authenticating to #{@hostname} as #{@vm_user} with key #{@vm_keyfile}" - Net::SCP.start(@hostname, @vm_user, :keys => [@vm_keyfile]) do |scp| - puts "DEBUG: uploading #{local} to #{remote}" - scp.upload!(local,remote) - end - else - Net::SCP.start(@hostname, @vm_user, :password => @vm_pass, :auth_methods => ["password"]) do |scp| - puts "DEBUG: uploading #{local} to #{remote}" - scp.upload!(local,remote) - end - end - end - - def scp_from(remote, local) - # download a file from a remote server - if @vm_keyfile - #puts "DEBUG: authenticating to #{@hostname} as #{@vm_user} with key #{@vm_keyfile}" - Net::SCP.start(@hostname, @vm_user, :keys => [@vm_keyfile]) do |scp| - puts "DEBUG: downloading #{remote} to #{local}" - scp.download!(remote,local) - end - else - Net::SCP.start(@hostname, @vm_user, :password => @vm_pass, :auth_methods => ["password"]) do |scp| - puts "DEBUG: downloading #{remote} to #{local}" - scp.download!(remote,local) - end - end - end - - def ssh_exec(command) - if @vm_keyfile - #puts "DEBUG: authenticating to #{@hostname} as #{@vm_user} with key #{@vm_keyfile}" - Net::SSH.start(@hostname, @vm_user, :keys => [@vm_keyfile]) do |ssh| - puts "DEBUG: running command: #{command}" - ssh.exec!(command) - end - else - Net::SSH.start(@hostname, @vm_user, :password => @vm_pass, :auth_methods => ["password"]) do |ssh| - result = ssh.exec!(command) - end - end - end - - def filter_input(string) - return "" unless string # nil becomes empty string - return unless string.class == String # Allow other types unmodified - - unless /^[\d\w\s\[\]\{\}\/\\\.\-\"\(\):!]*$/.match string - raise "WARNING! Invalid character in: #{string}" - end - string - end - - def filter_command(string) - return "" unless string # nil becomes empty string - return unless string.class == String # Allow other types unmodified - - unless /^[\d\w\s\[\]\{\}\/\\\.\-\"\(\)]*$/.match string - raise "WARNING! Invalid character in: #{string}" - end - string - end - -end -end -end diff --git a/src/lib/lab/driver/vsphere_driver.rb b/src/lib/lab/driver/vsphere_driver.rb deleted file mode 100644 index 89c066d..0000000 --- a/src/lib/lab/driver/vsphere_driver.rb +++ /dev/null @@ -1,120 +0,0 @@ -require 'vm_driver' - -## -## $Id$ -## - -# This driver was built against: -# VMware Vsphere 4.1 - -module Lab -module Drivers - -class VsphereDriver < VmDriver - - def initialize(config) - unless config['user'] then raise ArgumentError, "Must provide a username" end - unless config['host'] then raise ArgumentError, "Must provide a hostname" end - unless config[''] then raise ArgumentError, "Must provide a password" end - super(config) - - @user = filter_command(config['user']) - @host = filter_command(config['host']) - - # Soft dependency - begin - require 'rbvmomi' - rescue LoadError - raise "WARNING: Library rbvmomi not found. Could not create driver!" - end - - vim = RbVmomi::VIM.connect host: @host, user: @user, password: @pass - dc = vim.serviceInstance.find_datacenter("datacenter1") or fail "datacenter not found" - @vm = dc.find_vm("test") or fail "VM not found" - end - - def start - @vm.PowerOnVM_Task.wait_for_completion - end - - def stop - @vm.PowerOffVM_Task.wait_for_completion - end - - def suspend - @vm.SuspendVM_Task.wait_for_completion - end - - def pause - raise "Unimplemented" - end - - def resume - raise "Unimplemented" - end - - def reset - @vm.ResetVM_Task.wait_for_completion - end - - def create_snapshot(snapshot) - snapshot = filter_input(snapshot) - raise "Unimplemented" - end - - def revert_snapshot(snapshot) - raise "Unimplemented" - # If we got here, the snapshot didn't exist - raise "Invalid Snapshot Name" - end - - def delete_snapshot(snapshot, remove_children=false) - raise "Unimplemented" - # If we got here, the snapshot didn't exist - raise "Invalid Snapshot Name" - end - - def delete_all_snapshots - raise "Unimplemented" - end - - def run_command(command) - raise "Unimplemented" - end - - def copy_from(from, to) - if @os == "linux" - scp_from(from, to) - else - raise "Unimplemented" - end - end - - def copy_to(from, to) - if @os == "linux" - scp_to(from, to) - else - raise "Unimplemented" - end - end - - def check_file_exists(file) - raise "Unimplemented" - end - - def create_directory(directory) - raise "Unimplemented" - end - - def cleanup - raise "Unimplemented" - end - - def running? - raise "Unimplemented" - end - -end - -end -end diff --git a/src/lib/lab/driver/workstation_driver.rb b/src/lib/lab/driver/workstation_driver.rb deleted file mode 100644 index 60f3206..0000000 --- a/src/lib/lab/driver/workstation_driver.rb +++ /dev/null @@ -1,234 +0,0 @@ -require 'vm_driver' - -## -## $Id$ -## - -module Lab -module Drivers - -class WorkstationDriver < VmDriver - - def initialize(config) - super(config) - - if !File.exist?(@location) - raise ArgumentError,"Couldn't find: #{@location}" - end - end - - def start - system_command("vmrun -T ws start " + "\'#{@location}\' nogui") - end - - def stop - system_command("vmrun -T ws stop " + "\'#{@location}\' nogui") - end - - def suspend - system_command("vmrun -T ws suspend " + "\'#{@location}\' nogui") - end - - def pause - system_command("vmrun -T ws pause " + "\'#{@location}\' nogui") - end - - def reset - system_command("vmrun -T ws reset " + "\'#{@location}\' nogui") - end - - def create_snapshot(snapshot) - snapshot = filter_input(snapshot) - system_command("vmrun -T ws snapshot " + "\'#{@location}\' \'#{snapshot}\' nogui") - end - - def revert_snapshot(snapshot) - snapshot = filter_input(snapshot) - system_command("vmrun -T ws revertToSnapshot " + "\'#{@location}\' \'#{snapshot}\' nogui") - end - - def delete_snapshot(snapshot) - snapshot = filter_input(snapshot) - system_command("vmrun -T ws deleteSnapshot " + "\'#{@location}\' \'#{snapshot}\' nogui" ) - end - - def run_command(command) - - # - # Generate a script name - # - script_rand_name = rand(1000000) - - # - # Configure paths for each OS - We really can't filter command, so we're gonna - # stick it in a script - # - if @os == "windows" - local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.bat" - remote_tempfile_path = "C:\\\\lab_script_#{script_rand_name}.bat" - remote_output_file = "C:\\\\lab_command_output_#{script_rand_name}" - remote_run_command = remote_tempfile_path - File.open(local_tempfile_path, 'w') {|f| f.write(command) } - else - - local_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh" - remote_tempfile_path = "/tmp/lab_script_#{script_rand_name}.sh" - remote_output_file = "/tmp/lab_command_output_#{script_rand_name}" - local_output_file = "/tmp/lab_command_output_#{script_rand_name}" - - remote_run_command = remote_tempfile_path - - File.open(local_tempfile_path, 'w') {|f| f.write("#!/bin/sh\n#{command}\n")} - end - - if @tools - - #puts "DEBUG: Running w/ tools" - - # - # Copy our local tempfile to the guest - # - vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " + - "copyFileFromHostToGuest \'#{@location}\' \'#{local_tempfile_path}\'" + - " \'#{remote_tempfile_path}\'" - system_command(vmrunstr) - - if @os == "linux" - # - # Now run the command directly on the guest (linux - call w/ /bin/sh) - # - vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " + - "runProgramInGuest \'#{@location}\' /bin/sh #{remote_tempfile_path} > #{remote_output_file}" - system_command(vmrunstr) - else - # - # Now run the command directly on the guest (windows) - # - vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " + - "runProgramInGuest \'#{@location}\' #{remote_tempfile_path} > #{remote_output_file}" - system_command(vmrunstr) - end - - # - # Cleanup. Delete it on the guest - # - vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} " + - "deleteFileInGuest \'#{@location}\' \'#{remote_tempfile_path}\'" - system_command(vmrunstr) - - # - # Delete it locally - # - local_delete_command = "rm #{local_tempfile_path}" - system_command(local_delete_command) - else - - # - # Use SCP / SSH - # - - if @os == "linux" - - # - # Copy it over - # - scp_to(local_tempfile_path, remote_tempfile_path) - - # - # And ... execute it - # - ssh_exec("/bin/sh #{remote_tempfile_path} > #{remote_output_file}") - - # - # Now copy the output back to us - # - scp_from(remote_output_file, local_output_file) - - # Now, let's look at the output of the command - output_string = File.open(local_output_file,"r").read - - # - # And clean up - # - ssh_exec("rm #{remote_output_file}") - ssh_exec("rm #{remote_tempfile_path}") - - `rm #{local_output_file}` - - else - raise "Hey, no tools, and windows? can't do nuttin for ya man." - end - - end - output_string - end - - def copy_from(from, to) - from = filter_input(from) - to = filter_input(to) - if @tools - vmrunstr = "vmrun -T ws -gu \'#{@vm_user}\' -gp \'#{@vm_pass}\' copyFileFromGuestToHost " + - "\'#{@location}\' \'#{from}\' \'#{to}\'" - else - scp_from(from, to) - end - system_command(vmrunstr) - end - - def copy_to(from, to) - from = filter_input(from) - to = filter_input(to) - if @tools - vmrunstr = "vmrun -T ws -gu #{@vm_user} -gp #{@vm_pass} copyFileFromHostToGuest " + - "\'#{@location}\' \'#{from}\' \'#{to}\'" - system_command(vmrunstr) - else - scp_to(from, to) - end - end - - def check_file_exists(file) - file = filter_input(file) - if @tools - vmrunstr = "vmrun -T ws -gu \'#{@vm_user}\' -gp \'#{@vm_pass}\' fileExistsInGuest " + - "\'#{@location}\' \'#{file}\'" - system_command(vmrunstr) - else - raise "Unsupported" - end - end - - def create_directory(directory) - directory = filter_input(directory) - if @tools - vmrunstr = "vmrun -T ws -gu \'#{@vm_user}\' -gp \'#{@vm_pass}\' createDirectoryInGuest " + - " \'#{@location}\' \'#{directory}\' " - system_command(vmrunstr) - else - raise "Unsupported" - end - end - - def cleanup - - end - - def running? - ## Get running Vms - running = `vmrun list` - running_array = running.split("\n") - running_array.shift - - running_array.each do |vmx| - if vmx.to_s == @location.to_s - return true - end - end - - return false - end - -end - -end -end diff --git a/src/lib/lab/driver/workstation_vixr_driver.rb b/src/lib/lab/driver/workstation_vixr_driver.rb deleted file mode 100644 index ccedd1f..0000000 --- a/src/lib/lab/driver/workstation_vixr_driver.rb +++ /dev/null @@ -1,126 +0,0 @@ -require 'vm_driver' -## -## $Id$ -## - -# This requires rhythmx's vixr driver from https://github.com/rhythmx/vixr -# and below that, the VIX api from vmware http://www.vmware.com/support/developer/vix-api/ - -module Lab -module Drivers - -class WorkstationVixrDriver < VmDriver - - attr_accessor :type - attr_accessor :location - - def initialize(vmid, location, os=nil, tools=false, credentials=nil) - - # We have to treat this differently, as it's not in the same tree - begin - require 'vixr' - rescue LoadError - puts "WARNING: Library pro_vixr not found. To resolve this error, please\n" + - " install the vixr gem. Latest is available here:\n" + - "https://github.com/rhythmx/vixr ." - raise "Unable to create vixr driver" - end - - @vmid = filter_command(vmid) - @location = filter_command(location) - - if !File.exist?(@location) - raise ArgumentError,"Couldn't find: " + location - end - - @credentials = credentials - @tools = tools # not used in command lines, no filter - @os = os # not used in command lines, no filter - - # TODO - Currently only implemented for the first set - if @credentials.count > 0 - @vm_user = filter_input(@credentials[0]['user']) || "\'\'" - @vm_pass = filter_input(@credentials[0]['pass']) || "\'\'" - end - - host = VixR.connect() - vm = host.open_vmx(@location) - - end - - def start - vm.power_on - end - - def stop - vm.power_off - end - - def suspend - vm.suspend - end - - def pause - vm.pause - end - - def reset - vm.reset - end - - def create_snapshot(snapshot) - snapshot = filter_input(snapshot) - system_command("ssh #{@user}@#{@host} vmrun -T ws snapshot \\\'#{@location}\\\' #{snapshot} nogui") - end - - def revert_snapshot(snapshot) - snapshot = filter_input(snapshot) - system_command("ssh #{@user}@#{@host} vmrun -T ws revertToSnapshot \\\'#{@location}\\\' #{snapshot} nogui") - end - - def delete_snapshot(snapshot) - snapshot = filter_input(snapshot) - system_command("ssh #{@user}@#{@host} vmrun -T ws deleteSnapshot \\\'#{@location}\\\' #{snapshot} nogui" ) - end - - - def run_command(command) - command = filter_input(command) - if vm.login(@vm_user,@vm_pass) - vm.run_prog(command) - end - end - - def copy_from(from, to) - from = filter_input(from) - to = filter_input(to) - cp_from_host(from,to) - end - - def copy_to(from, to) - from = filter_input(from) - to = filter_input(to) - vm.cp_to_guest(from,to) - end - - def check_file_exists(file) - file = filter_input(file) - file_exists?(file) - end - - def create_directory(directory) - directory = filter_input(directory) - end - - def cleanup - - end - - def running? - vm.running? - end - -end - -end -end diff --git a/src/lib/lab/drivers.rb b/src/lib/lab/drivers.rb deleted file mode 100644 index 94c16b7..0000000 --- a/src/lib/lab/drivers.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'driver/workstation_driver' -require 'driver/virtualbox_driver' -require 'driver/fog_driver' -require 'driver/dynagen_driver' -require 'driver/remote_workstation_driver' -require 'driver/remote_esxi_driver' -require 'driver/vsphere_driver' -#require 'driver/qemu_driver' -#require 'driver/qemudo_driver' diff --git a/src/lib/lab/modifier/backtrack5_modifier.rb b/src/lib/lab/modifier/backtrack5_modifier.rb deleted file mode 100644 index c3e7cab..0000000 --- a/src/lib/lab/modifier/backtrack5_modifier.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Lab -module Modifier -module Backtrack5 - - def nmap(options) - run_command("nmap #{filter_input(options)}") - end - - def testssl(site) - run_command("/pentest/scanners/testssl/testssl.sh #{filter_input(site)}") - end - -end -end -end - diff --git a/src/lib/lab/modifier/dos_modifier.rb b/src/lib/lab/modifier/dos_modifier.rb deleted file mode 100644 index 190442e..0000000 --- a/src/lib/lab/modifier/dos_modifier.rb +++ /dev/null @@ -1,14 +0,0 @@ -# This assumes you're on a recent ubuntu -# TODO - enforce this, or split it out... - -module Lab -module Modifier -module Dos - - def ping(target) - run_command("ping #{filter_input(target)}") - end - -end -end -end diff --git a/src/lib/lab/modifier/test_modifier.rb b/src/lib/lab/modifier/test_modifier.rb deleted file mode 100644 index e6bea2a..0000000 --- a/src/lib/lab/modifier/test_modifier.rb +++ /dev/null @@ -1,16 +0,0 @@ -# This assumes you're on a recent ubuntu -# TODO - enforce this, or split it out... - -module Lab -module Modifier -module Test - def install_nmap - run_command("sudo apt-get install nmap") - end - - def nmap(options) - run_command("nmap #{filter_input(options)}") - end -end -end -end diff --git a/src/lib/lab/modifiers.rb b/src/lib/lab/modifiers.rb deleted file mode 100644 index 288f790..0000000 --- a/src/lib/lab/modifiers.rb +++ /dev/null @@ -1,3 +0,0 @@ -require 'modifier/test_modifier' -require 'modifier/backtrack5_modifier' -require 'modifier/dos_modifier' diff --git a/src/lib/lab/version.rb b/src/lib/lab/version.rb deleted file mode 100644 index a4188bd..0000000 --- a/src/lib/lab/version.rb +++ /dev/null @@ -1,3 +0,0 @@ -module Lab - VERSION = "0.2.0" -end diff --git a/src/lib/lab/vm.rb b/src/lib/lab/vm.rb deleted file mode 100644 index 319607a..0000000 --- a/src/lib/lab/vm.rb +++ /dev/null @@ -1,269 +0,0 @@ -# -module Lab - -# -# This class encapsulates a vm, provides functionality on that vm, and contains a single driver. -# -class Vm - - attr_accessor :vmid - attr_accessor :hostname - attr_accessor :description - attr_accessor :user - attr_accessor :host - attr_accessor :location - attr_accessor :driver - attr_accessor :credentials - attr_accessor :tools - attr_accessor :type - attr_accessor :os - attr_accessor :arch - attr_accessor :tags - - ## Initialize takes a vm configuration hash of the form - ## - vmid (unique id) - ## hostname (unique name) - ## description (describes the vm's contents) - ## driver (vm driver) - ## location (if applicable - local system) - ## user (if applicable - remote system) - ## host (if applicable - remote system) - ## pass (if applicable - remote system) # DISCOURAGED - USE KEYS! - ## tools (true if tools are installed) - ## type ( qa / vulnerable / etc - freeform option) - ## credentials (of the form [ {'user'=>"user",'pass'=>"pass", 'admin' => false}, ... ]) - ## os (currently linux / windows / solaris / aix) - may be used in modifiers - ## arch (currently 32 / 64) - ## modifiers - array of strings, can be anything in the modifiers directory - ## tags - array of strings associated with this vm - - def initialize(config = {}) - - # TODO - This is a mess. clean up, and pass stuff down to drivers - # and then rework the code that uses this api. - @vmid = config['vmid'].to_s - raise "Invalid VMID" unless @vmid - - # Grab the hostname if specified, otherwise use the vmid - # VMID will be different in the case of ESX - @hostname = config['hostname'] - if !@hostname - @hostname = @vmid - end - - @driver_type = filter_input(config['driver']) - @driver_type.downcase! - - @location = filter_input(config['location']) - @description = config['description'] - @tools = config['tools'] - @os = config['os'] - @arch = config['arch'] - @type = filter_input(config['type']) || "unspecified" - @credentials = config['credentials'] || [] - - # TODO - Currently only implemented for the first set - if @credentials.count > 0 - @vm_user = filter_input(@credentials[0]['user']) || "\'\'" - @vm_pass = filter_input(@credentials[0]['pass']) || "\'\'" - @vm_keyfile = filter_input(@credentials[0]['keyfile']) - end - - # Only applicable to remote systems - @user = filter_input(config['user']) || nil - @host = filter_input(config['host']) || nil - @port = filter_input(config['port']) || nil - @pass = filter_input(config['pass']) || nil # DISCORAGED, use keys! - - # Only dynagen systems need this - @platform = config['platform'] - - # Only fog systems need this - @fog_config = config['fog_config'] - - # Process the correct driver - if @driver_type == "workstation" - @driver = Lab::Drivers::WorkstationDriver.new(config) - elsif @driver_type == "remote_workstation" - @driver = Lab::Drivers::RemoteWorkstationDriver.new(config) - elsif @driver_type == "virtualbox" - @driver = Lab::Drivers::VirtualBoxDriver.new(config) - elsif @driver_type == "fog" - @driver = Lab::Drivers::FogDriver.new(config, config['fog_config']) - elsif @driver_type == "dynagen" - @driver = Lab::Drivers::DynagenDriver.new(config, config['dynagen_config']) - elsif @driver_type == "remote_esxi" - @driver = Lab::Drivers::RemoteEsxiDriver.new(config) - elsif @driver_type == "vsphere" - @driver = Lab::Drivers::VsphereDriver.new(config) - #elsif @driver_type == "qemu" - # @driver = Lab::Drivers::QemuDriver.new - #elsif @driver_type == "qemudo" - # @driver = Lab::Drivers::QemudoDriver.new - else - raise "Unknown Driver Type" - end - - # Load in a list of modifiers. These provide additional methods - # Currently it is up to the user to verify that - # modifiers are properly used with the correct VM image. - # - # If not, the results are likely to be disasterous. - @modifiers = config['modifiers'] - - if @modifiers - begin - @modifiers.each { |modifier| self.class.send(:include, eval("Lab::Modifier::#{modifier}"))} - rescue Exception => e - # modifier likely didn't exist - end - end - - # - # Grab a tags array - # - @tags = config['tags'] - - end - - def running? - @driver.running? - end - - def location - @driver.location - end - - def start - @driver.start - end - - def stop - @driver.stop - end - - def pause - @driver.pause - end - - def suspend - @driver.suspend - end - - def reset - @driver.reset - end - - def resume - @driver.resume - end - - def create_snapshot(snapshot) - @driver.create_snapshot(snapshot) - end - - def revert_snapshot(snapshot) - @driver.revert_snapshot(snapshot) - end - - def delete_snapshot(snapshot) - @driver.delete_snapshot(snapshot) - end - - def revert_and_start(snapshot) - @driver.revert_snapshot(snapshot) - @driver.start - end - - def copy_to(from,to) - @driver.copy_to(from,to) - end - - def copy_from(from,to) - @driver.copy_from(from,to) - end - - def run_command(command) - @driver.run_command(command) - end - - def check_file_exists(file) - @driver.check_file_exists(file) - end - - def create_directory(directory) - @driver.create_directory(directory) - end - - def open_uri(uri) - # we don't filter the uri, as it's getting tossed into a script - # by the driver - if @os == "windows" - command = "\"C:\\program files\\internet explorer\\iexplore.exe\" #{uri}" - else - command = "firefox #{uri}" - end - - @driver.run_command(command) - end - - def to_s - return "#{@hostname}" - end - - def to_yaml - - # TODO - push this down to the drivers. - - # Standard configuration options - out = " - vmid: #{@vmid}\n" - out += " hostname: #{@hostname}\n" - out += " driver: #{@driver_type}\n" - out += " description: |\n #{@description}\n" - out += " location: #{@location}\n" - out += " type: #{@type}\n" - out += " tools: #{@tools}\n" - out += " os: #{@os}\n" - out += " arch: #{@arch}\n" - - if @user or @host # Remote vm/drivers only - out += " user: #{@user}\n" - out += " host: #{@host}\n" - out += " port: #{@port}\n" - out += " pass: #{@pass}\n" - end - - if @platform - out += " platform: #{@platform}\n" - end - - if @fog_config - out += @fog_config.to_yaml - end - - if @dynagen_config - out += @dynagen_config.to_yaml - end - - out += " credentials:\n" - @credentials.each do |credential| - out += " - user: #{credential['user']}\n" - out += " pass: #{credential['pass']}\n" - end - - return out - end -private - - def filter_input(string) - return "" unless string # nil becomes empty string - return unless string.class == String # Allow other types - - unless /^[(!)\d*\w*\s*\[\]\{\}\/\\\.\-\"\(\)]*$/.match string - raise "WARNING! Invalid character in: #{string}" - end - - string - end -end -end diff --git a/src/lib/lab/vm_controller.rb b/src/lib/lab/vm_controller.rb deleted file mode 100644 index 6de6296..0000000 --- a/src/lib/lab/vm_controller.rb +++ /dev/null @@ -1,275 +0,0 @@ -# -# $Id$ -# -# This is the main lab controller. Require this controller to get all -# lab functionality. -# -# - -$:.unshift(File.expand_path(File.dirname(__FILE__))) -$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'driver'))) -$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'controller'))) -$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'modifier'))) - -require 'find' -require 'yaml' -require 'enumerator' -require 'fileutils' - -require 'vm' -require 'controllers' -require 'drivers' -require 'modifiers' - -require 'net/scp' -require 'net/ssh' - -module Lab -module Controllers - class VmController - - include Enumerable - include Lab::Controllers::WorkstationController - include Lab::Controllers::RemoteWorkstationController - include Lab::Controllers::VirtualBoxController - include Lab::Controllers::FogController - include Lab::Controllers::DynagenController - include Lab::Controllers::RemoteEsxiController - include Lab::Controllers::VsphereController - #include Lab::Controllers::QemuController - #include Lab::Controllers::QemudoController - def initialize (labdef=nil) - - # Start with an empty array of vm objects - @vms = [] - - # labdef is a just a big array of hashes - load_vms(labdef) if labdef - end - - def clear! - @vms = [] - end - - def [](x) - # Support indexing by both names and number - if x.class == String - find_by_vmid(x) - else - return @vms[x] - end - end - - def find_by_vmid(search) - @vms.each do |vm| - return vm if vm.hostname.to_s.downcase == search.to_s.downcase - end - return nil - end - - def find_by_tag(search) - @vms.each do |vm| - vm.tags.each do |tag| - return vm if tag.downcase == search.to_s.downcase - end - end - return nil - end - - def add_vm(vmid, location=nil, os=nil, tools=nil, credentials=nil, user=nil, host=nil) - @vms << Vm.new( { - 'vmid' => vmid, - 'driver' => type, - 'location' => location, - 'credentials' => credentials, - 'user' => user, - 'host' => host - }) - end - - def remove_by_vmid(vmid) - @vms.delete(self.find_by_vmid(vmid)) - end - - def from_file(file) - load_vms(YAML::load_file(file)) - end - - def load_vms(vms) - vms.each do |item| - vm = Vm.new(item) - @vms << vm unless includes_vmid? vm.vmid - end - end - - def to_file(file) - File.open(file, 'w') { |f| @vms.each { |vm| f.puts vm.to_yaml } } - end - - def each &block - @vms.each { |vm| yield vm } - end - - def includes?(specified_vm) - @vms.each { |vm| if (vm == specified_vm) then return true end } - end - - def includes_vmid?(vmid) - @vms.each do |vm| - return true if (vm.vmid == vmid) - end - false - end - - # - # Build a vm lab from a directory of files. Really only useful for file-based - # vm hosts. (vmware workstation) - # - def build_from_dir(driver_type, dir, clear=false) - - if clear - @vms = [] - end - - if driver_type.downcase == "workstation" - vm_list = ::Lab::Controllers::WorkstationController::dir_list(dir) - elsif driver_type.downcase == "remote_workstation" - vm_list = ::Lab::Controllers::RemoteWorkstationController::dir_list(dir) - elsif driver_type.downcase == "virtualbox" - vm_list = ::Lab::Controllers::VirtualBoxController::dir_list(dir) - elsif driver_type.downcase == "fog" - vm_list = ::Lab::Controllers::FogController::dir_list(dir) - elsif driver_type.downcase == "Dynagen" - vm_list = ::Lab::Controllers::DynagenController::dir_list(dir) - elsif driver_type.downcase == "remote_esxi" - vm_list =::Lab::Controllers::RemoteEsxiController::dir_list(dir) - elsif driver_type.downcase == "vsphere" - vm_list =::Lab::Controllers::VsphereController::dir_list(dir) - else - raise TypeError, "Unsupported VM Type" - end - - vm_list.each_index do |index| - @vms << Vm.new( {'vmid' => "vm_#{index}", 'driver' => driver_type, 'location' => vm_list[index]} ) - end - end - - - # - # Builds a vm lab from all running vms. Handy for connecting and saving out - # a config or just managing the currently running vms - # - def build_from_running(driver_type=nil, user=nil, host=nil, clear=false, pass=nil) - - if clear - @vms = [] - end - - case driver_type.intern - when :workstation - vm_list = ::Lab::Controllers::WorkstationController::running_list - vm_list.each do |item| - # Name the VM - index = @vms.count + 1 - # Add it to the vm list - @vms << Vm.new({ - 'vmid' => "vm_#{index}", - 'driver' => driver_type, - 'location' => item - }) - end - when :remote_workstation - vm_list = ::Lab::Controllers::RemoteWorkstationController::running_list(user, host) - vm_list.each do |item| - # Name the VM - index = @vms.count + 1 - # Add it to the VM list - @vms << Vm.new({ - 'vmid' => "vm_#{index}", - 'driver' => driver_type, - 'location' => item, - 'user' => user, - 'host' => host - }) - end - when :virtualbox - vm_list = ::Lab::Controllers::VirtualBoxController::running_list - vm_list.each do |item| - # Add it to the vm list - @vms << Vm.new( { - 'vmid' => "#{item}", - 'driver' => driver_type, - 'location' => nil - }) - end - when :fog - raise "Unsupported" - when :dynagen - raise "Unsupported" - when :remote_esxi - vm_list = ::Lab::Controllers::RemoteEsxiController::running_list(user,host) - vm_list.each do |item| - @vms << Vm.new( { - 'vmid' => "#{item[:id]}", - 'name' => "#{item[:name]}", - 'driver' => driver_type, - 'user' => user, - 'host' => host - }) - end - when :vsphere - vm_list = ::Lab::Controllers::VsphereController::running_list(user,host,pass) - vm_list.each do |item| - @vms << Vm.new( { - 'vmid' => "#{item[:id]}", - 'name' => "#{item[:name]}", - 'driver' => driver_type, - 'user' => user, - 'host' => host, - 'pass' => pass - }) - end - else - raise TypeError, "Unsupported VM Type" - end - - end - - # - # Applicable only to virtualbox. Reads the config file & parses / creates - # VM objects for each vm. - # - def build_from_config(driver_type=nil, user=nil, host=nil, clear=false) - if clear - @vms = [] - end - - case driver_type.intern - when :virtualbox - vm_list = ::Lab::Controllers::VirtualBoxController::config_list - - vm_list.each do |item| - # Add it to the vm list - @vms << Vm.new( { - 'vmid' => "#{item}", - 'driver' => driver_type, - 'location' => nil, - 'user' => user, - 'host' => host } ) - end - - else - raise TypeError, "Unsupported VM Type" - end - - end - - def running?(vmid) - if includes_vmid?(vmid) - return self.find_by_vmid(vmid).running? - end - return false - end - end -end -end diff --git a/src/test/.gitkeep b/src/test/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/util/console.rb b/util/console.rb new file mode 100755 index 0000000..563db1c --- /dev/null +++ b/util/console.rb @@ -0,0 +1,10 @@ +#!/usr/bin/env ruby +require 'pry' +require "#{File.expand_path(File.dirname(__FILE__))}/../lib/lab/vm_controller" + +@controller = Lab::Controllers::VmController.new +@controller.from_file("#{File.expand_path(File.dirname(__FILE__))}/../config/test_lab.yml") + +ENV['SSL_CERT_FILE'] = "/home/jcran/.cacert.pem" + +Pry.start(self, :prompt => [proc{"lab (@controller) >"}])