vmesh 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitattributes ADDED
@@ -0,0 +1 @@
1
+ * eol=lf
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *~
2
+ *swp
3
+ *idea
4
+ *.swo
5
+ vmesh*.gem
6
+ vendor
7
+ results.html
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ #gem 'rbvmomi', :git => 'https://github.com/vmware/rbvmomi.git'
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,62 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ vmesh (0.1.3)
5
+ gli (= 2.9.0)
6
+ highline (~> 1.6)
7
+ logger (= 1.2.8)
8
+ nokogiri (~> 1.6)
9
+ rbvmomi (= 1.8.2)
10
+
11
+ GEM
12
+ remote: https://rubygems.org/
13
+ specs:
14
+ aruba (0.5.4)
15
+ childprocess (>= 0.3.6)
16
+ cucumber (>= 1.1.1)
17
+ rspec-expectations (>= 2.7.0)
18
+ builder (3.2.2)
19
+ childprocess (0.5.1)
20
+ ffi (~> 1.0, >= 1.0.11)
21
+ cucumber (1.3.13)
22
+ builder (>= 2.1.2)
23
+ diff-lcs (>= 1.1.3)
24
+ gherkin (~> 2.12)
25
+ multi_json (>= 1.7.5, < 2.0)
26
+ multi_test (>= 0.1.1)
27
+ diff-lcs (1.2.5)
28
+ ffi (1.9.3)
29
+ gherkin (2.12.2)
30
+ multi_json (~> 1.3)
31
+ gli (2.9.0)
32
+ highline (1.6.21)
33
+ json (1.8.1)
34
+ logger (1.2.8)
35
+ metaclass (0.0.4)
36
+ mini_portile (0.6.0)
37
+ mocha (1.0.0)
38
+ metaclass (~> 0.0.1)
39
+ multi_json (1.10.0)
40
+ multi_test (0.1.1)
41
+ nokogiri (1.6.3.1)
42
+ mini_portile (= 0.6.0)
43
+ rake (10.3.1)
44
+ rbvmomi (1.8.2)
45
+ builder
46
+ nokogiri (>= 1.4.1)
47
+ trollop
48
+ rdoc (4.1.1)
49
+ json (~> 1.4)
50
+ rspec-expectations (2.14.5)
51
+ diff-lcs (>= 1.1.3, < 2.0)
52
+ trollop (2.0)
53
+
54
+ PLATFORMS
55
+ ruby
56
+
57
+ DEPENDENCIES
58
+ aruba (= 0.5.4)
59
+ mocha (= 1.0.0)
60
+ rake (= 10.3.1)
61
+ rdoc (= 4.1.1)
62
+ vmesh!
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) [year] [fullname]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # Command suite for VMWare
2
+
3
+ ## What is Vmesh?
4
+
5
+ Vmesh is a Command Suite (think git) to make managing VMWare components easier and possible without leaving your local machine.
6
+
7
+ ##THIS IS ALPHA!
8
+
9
+ Vmesh is currently Alpha, hence the 0-dot version; it is susceptible to methods, classes and modules being renamed, added or deleted.
10
+
11
+ ## Setup
12
+
13
+ Install the gem
14
+
15
+ ```
16
+ gem install vmesh
17
+ ```
18
+
19
+ You can now start using it, e.g. list top level dirs
20
+ ```
21
+ vmesh --datacenter=my.datacenter.com --host=my.vcenter.host.com ls
22
+ ```
23
+
24
+ #### I don't want to type my connection config every time
25
+
26
+ Vmesh can save config so you don't have to type it each time, use initconfig with an alias like so
27
+
28
+ ```
29
+ vmesh my_alias --datacenter=my.datacenter.com --host=my.vcenter.host.com initconfig
30
+ ```
31
+
32
+ Commands are now as easy as
33
+
34
+ ```
35
+ vmesh my_alias ls
36
+ ```
37
+
38
+ #### How to setup cloning servers
39
+
40
+ Define the image types, their relevant template and any custom specs by editing the `server_defaults.rb` file
41
+
42
+ ```
43
+ lib/vmesh/server_defaults.rb
44
+ ```
45
+
46
+ e.g. an entry similar to
47
+ ```
48
+ :linux => {
49
+ :name => 'Templates/CENTOS_6',
50
+ :spec => 'Linux No Prompt'
51
+ },
52
+ ```
53
+
54
+ then to create a server named `vmlinux01` cloned from `'Templates/CENTOS_6'` template using a custom spec called `Linux No Prompt`
55
+
56
+ ```
57
+ vmesh create vmlinux01 linux
58
+ ```
59
+
60
+ #### AMG It complains about vtypes and stuff
61
+
62
+ * There is (or at least was?) an Rbvmomi hack required for nokogiri breaking change in 1.6.1, I'm still trying to figure the best way around this...
63
+
64
+ * https://github.com/vmware/rbvmomi/pull/32
65
+
66
+
67
+ ## Usage
68
+
69
+ ### Help
70
+
71
+ Get help
72
+
73
+ ```
74
+ vmesh --help
75
+ ```
76
+
77
+ Help on a specific command
78
+
79
+ ```
80
+ vmesh create --help
81
+ ```
82
+
83
+ ### Create or clone
84
+
85
+ ###### IP Handling
86
+ For multiple servers vmesh automatically increments the IP Address, e.g.
87
+ ```
88
+ vmesh create vmweb01,vmweb02 linux --ip_address='192.168.0.10'
89
+ ```
90
+ will create the following servers
91
+ || server name || ip ||
92
+ | vmweb01 | 192.168.0.10 |
93
+ | vmweb02 | 192.168.0.11 |
94
+
95
+ Of course you can just comma separate the IPs too
96
+ ```
97
+ vmesh create vmweb01,vmweb02 linux --ip_address='192.168.0.10','192.168.0.11'
98
+ ```
99
+
100
+ ###### How vmesh deals with datastores
101
+ When specifying datastore vmesh will use a datastore matching name exactly, if it doesn't find a match it will gets all datastores with this string in their name then uses the one with the most free space.
102
+
103
+ ```
104
+ vmesh create my_vm_name2 windows12 [--ip_address='<ip_address>'] --datastore='SEARCH_STRING' [--folder='DESTINATION_FOLDER']
105
+ ```
106
+ e.g. for the above, if datastores exist with names FIRST_SEARCH_STRING, ANOTHER_SEARCH_STRING it will find both (as they both contain "SEARCH_STRING") then use the one with the most free space.
107
+
108
+ ### Power
109
+
110
+ To change the power state of a VM
111
+
112
+ ```
113
+ vmesh power 'folder/machine_name' on
114
+ ```
115
+
116
+ ```
117
+ vmesh power 'folder/machine_name' off
118
+ ```
119
+
120
+ ##### Deleting a VM can be done with the command
121
+
122
+ ```
123
+ vmesh power 'folder/machine_name' destroy
124
+ ```
125
+
126
+ ### List
127
+
128
+ _Note_ you can use `ls`, `dir` or `list`
129
+
130
+ List vms and directories at the top level
131
+
132
+ ```
133
+ vmesh ls
134
+ ```
135
+
136
+ List recursively
137
+
138
+ ```
139
+ vmesh ls -r
140
+ ```
141
+
142
+ List directories only
143
+
144
+ ```
145
+ vmesh ls -d
146
+ ```
147
+
148
+ ## TODOs
149
+
150
+ * Sort out problem with upstream rbvmomi/nogokiri
151
+
152
+ * Related bug here https://github.com/nsidc/vagrant-vsphere/issues/28
153
+
154
+ * Create
155
+
156
+ * Don't create new vm if less than 10% space
157
+
158
+ * Power
159
+
160
+ * Query & display state after operation completes
161
+
162
+ * General
163
+
164
+ * Performance enhancements would be nice
165
+
166
+ * Server defaults in external configuration, e.g. Symlink to config/shared/ or etcd
167
+
168
+ * Vmesh everything else :-)
169
+
170
+
171
+ ## Copyright
172
+
173
+ Copyright (c) 2014 Kurt Gardiner. See LICENSE.txt for further details.
174
+
175
+
data/README.rdoc ADDED
@@ -0,0 +1,6 @@
1
+ = vmesh
2
+
3
+ Describe your project here
4
+
5
+ :include:vmesh.rdoc
6
+
data/Rakefile ADDED
@@ -0,0 +1,44 @@
1
+ require 'rake/clean'
2
+ require 'rubygems'
3
+ require 'rubygems/package_task'
4
+ require 'rdoc/task'
5
+ require 'cucumber'
6
+ require 'cucumber/rake/task'
7
+ Rake::RDocTask.new do |rd|
8
+ rd.main = "README.rdoc"
9
+ rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
10
+ rd.title = 'Your application title'
11
+ end
12
+
13
+ spec = eval(File.read('vmesh.gemspec'))
14
+
15
+ Gem::PackageTask.new(spec) do |pkg|
16
+ end
17
+ CUKE_RESULTS = 'results.html'
18
+ CLEAN << CUKE_RESULTS
19
+ desc 'Run features'
20
+ Cucumber::Rake::Task.new(:features) do |t|
21
+ opts = "features --format html -o #{CUKE_RESULTS} --format progress -x"
22
+ opts += " --tags #{ENV['TAGS']}" if ENV['TAGS']
23
+ t.cucumber_opts = opts
24
+ t.fork = false
25
+ end
26
+
27
+ desc 'Run features tagged as work-in-progress (@wip)'
28
+ Cucumber::Rake::Task.new('features:wip') do |t|
29
+ tag_opts = ' --tags ~@pending'
30
+ tag_opts = ' --tags @wip'
31
+ t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty -x -s#{tag_opts}"
32
+ t.fork = false
33
+ end
34
+
35
+ task :cucumber => :features
36
+ task 'cucumber:wip' => 'features:wip'
37
+ task :wip => 'features:wip'
38
+ require 'rake/testtask'
39
+ Rake::TestTask.new do |t|
40
+ t.libs << "test"
41
+ t.test_files = FileList['test/*_test.rb']
42
+ end
43
+
44
+ task :default => [:test,:features]
data/bin/vmesh ADDED
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gli'
3
+ begin # XXX: Remove this begin/rescue before distributing your app
4
+ require 'vmesh'
5
+ require 'logger'
6
+ require 'highline/import'
7
+
8
+ rescue LoadError
9
+ STDERR.puts "In development, you need to use `bundle exec bin/vmesh` to run your app"
10
+ STDERR.puts "At install-time, RubyGems will make sure lib, etc. are in the load path"
11
+ STDERR.puts "Feel free to remove this message from bin/vmesh now"
12
+ exit 64
13
+ end
14
+
15
+ include GLI::App
16
+
17
+ version Vmesh::VERSION
18
+ Vmesh.logger = Logger.new(STDOUT)
19
+ @logger = Vmesh.logger
20
+
21
+
22
+ config_filename = '.vmesh.rc'
23
+
24
+ def check_migrate
25
+ Dir.glob(File.join(File.expand_path(ENV['HOME']),'.mesh.*.rc')).each do |mesh_file|
26
+ new_name = mesh_file.gsub('.mesh','.vmesh')
27
+ Vmesh.logger.info "Migrating #{mesh_file} from #{File.basename(mesh_file)} to #{new_name}"
28
+ File.rename mesh_file, new_name
29
+ end
30
+ end
31
+
32
+ check_migrate
33
+
34
+ if ARGV.count >= 2
35
+ host_alias = ARGV[0]
36
+ init_config = (ARGV.last == 'initconfig')
37
+ if init_config or File.exist? File.join(File.expand_path(ENV['HOME']),".vmesh.#{host_alias}.rc")
38
+ config_filename = ".vmesh.#{host_alias}.rc"
39
+ Vmesh.logger.info "Using host specific config file ~/.vmesh.#{host_alias}.rc"
40
+ ARGV.shift
41
+ else
42
+ Vmesh.logger.info "No site specific config file found, using default ~/#{config_filename}."
43
+ end
44
+ end
45
+
46
+ config_file config_filename
47
+
48
+ program_desc 'VMWare VSphere command suite interface'
49
+ program_long_desc 'A command suite to allow users to manage VMWare virtual machines remotely via the command line'
50
+
51
+ desc 'Ignore SSL Certificate errors in connection'
52
+ switch [:insecure]
53
+
54
+ desc 'VCenter username'
55
+ arg_name 'user'
56
+ flag [:u,:user]
57
+
58
+ desc 'VCenter password'
59
+ arg_name 'password'
60
+ flag [:p,:password]
61
+
62
+ desc 'VCenter host'
63
+ arg_name 'vcenter host'
64
+ flag [:h,:host]
65
+
66
+ desc 'Datacenter'
67
+ arg_name 'datacenter'
68
+ flag [:d,:datacenter]
69
+
70
+ desc 'VCenter Resource Pool'
71
+ arg_name 'vcenter resource pool'
72
+ flag [:r,:resource_pool]
73
+
74
+ commands_from 'vmesh/commands'
75
+
76
+ desc 'TODO Describe destroy here'
77
+ arg_name 'Describe arguments to destroy here'
78
+ command :destroy do |c|
79
+ c.action do |global_options,options,args|
80
+ puts "destroy command ran"
81
+ end
82
+ end
83
+
84
+ desc 'TODO Describe run here'
85
+ arg_name 'Describe arguments to run here'
86
+ command :run do |c|
87
+ c.action do |global_options,options,args|
88
+ puts "run command ran"
89
+ end
90
+ end
91
+
92
+ desc 'TODO Describe info here'
93
+ arg_name 'Describe arguments to info here'
94
+ command :info do |c|
95
+ c.action do |global_options,options,args|
96
+ puts "info command ran"
97
+ end
98
+ end
99
+
100
+ pre do |global,command,options,args|
101
+ # Pre logic here
102
+ # Return true to proceed; false to abort and not call the
103
+ # chosen command
104
+ # Use skips_pre before a command to skip this block
105
+ # on that command only
106
+ if global[:user].to_s == ''
107
+ not_so_secret_username = ask("Enter Username please:") {|q| q.echo = true}
108
+ global['u'] = global[:u] = global['user'] = global[:user] = not_so_secret_username
109
+ end
110
+
111
+ if global[:password].to_s == ''
112
+ the_super_secret_password = ask("Enter Password for #{global[:user]} please:") {|q| q.echo = false}
113
+ global['p'] = global[:p] = global['password'] = global[:password] = the_super_secret_password
114
+ end
115
+ true
116
+ end
117
+
118
+ post do |global,command,options,args|
119
+ # Post logic here
120
+ # Use skips_post before a command to skip this
121
+ # block on that command only
122
+ end
123
+
124
+ on_error do |exception|
125
+ # Error logic here
126
+ # return false to skip default error handling
127
+ true
128
+ end
129
+
130
+ exit run(ARGV)
@@ -0,0 +1,9 @@
1
+ =begin
2
+ When /^I create with no arguments$/ do
3
+ step %(I run `vmesh create`)
4
+ end
5
+ =end
6
+
7
+ When /^I create with "([^"]*)" template and name "([^"]*)"$/ do |type, name|
8
+ step %(I run `vmesh -u user -p fakepass create #{name} #{type}`)
9
+ end
@@ -0,0 +1,3 @@
1
+ When /^I power machine "([^"]*)" into state "([^"]*)"$/ do |machine, desired_state|
2
+ step %(I run `vmesh -u user -p secret power #{machine} #{desired_state}`)
3
+ end
@@ -0,0 +1,9 @@
1
+ When /^I (.*) with no arguments$/ do |command|
2
+ step %(I run `vmesh -u user -p fake #{command}`)
3
+ end
4
+
5
+ When /^I get help for "([^"]*)"$/ do |app_name|
6
+ @app_name = app_name
7
+ step %(I run `#{app_name} --help`)
8
+ end
9
+
@@ -0,0 +1,15 @@
1
+ require 'aruba/cucumber'
2
+
3
+ ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
4
+ LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
5
+
6
+ Before do
7
+ # Using "announce" causes massive warnings on 1.9.2
8
+ @puts = true
9
+ @original_rubylib = ENV['RUBYLIB']
10
+ ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
11
+ end
12
+
13
+ After do
14
+ ENV['RUBYLIB'] = @original_rubylib
15
+ end
@@ -0,0 +1,14 @@
1
+ Feature: Create a new VM
2
+ In order to provision new infrastructure
3
+ I want to be able to create new templated VMs
4
+ So I have consistent easily created VMs
5
+
6
+ Scenario: Create with no arguments
7
+ When I create with no arguments
8
+ Then the exit status should be 1
9
+
10
+ Scenario: Create with unknown vm type
11
+ When I create with "unknown" template and name "anything"
12
+ Then the exit status should be 1
13
+ And the stderr should contain "unknown machine type"
14
+
@@ -0,0 +1,18 @@
1
+ Feature: My bootstrapped app kinda works
2
+ In order to get going on coding my awesome app
3
+ I want to have aruba and cucumber setup
4
+ So I don't have to do it myself
5
+
6
+ Scenario: vmesh just runs
7
+ When I get help for "vmesh"
8
+ Then the exit status should be 0
9
+
10
+
11
+ Scenario: vmesh create just runs
12
+ When I get help for "vmesh create"
13
+ Then the exit status should be 0
14
+
15
+ Scenario: vmesh power just runs
16
+ When I get help for "vmesh power"
17
+ Then the exit status should be 0
18
+
@@ -0,0 +1,12 @@
1
+ Feature: Change Power State of a VM
2
+ In order to manage servers
3
+ I want to be able to change the power state of VMs
4
+ So I can easily manage these servers
5
+
6
+ Scenario: Power with no arguments
7
+ When I power with no arguments
8
+ Then the exit status should be 1
9
+
10
+ Scenario: Power vm into an unknown state
11
+ When I power machine "vmfrozen01" into state "unfrozed"
12
+ Then the exit status should be 1
@@ -0,0 +1,65 @@
1
+ require 'ipaddr'
2
+
3
+ desc 'create a new virtual machine'
4
+ arg_name 'folder/name[,folder/name_of_second_machine] type'
5
+
6
+ command :create do |c|
7
+ c.desc 'Destination datastore, full or partial match'
8
+ c.long_desc 'Destination datastore, full or partial match, partial match will use datastore including the string with the greatest free space'
9
+ c.flag [:s, :datastore]
10
+
11
+ c.desc 'Destination folder where not supplied with name'
12
+ c.long_desc 'Destination folder for the vm(s), will be ignored for any vms with a folder supplied as part of the name'
13
+ c.flag [:f, :folder]
14
+
15
+ # This wasn't working for what-ever reason, no error, just no effect
16
+ #c.desc 'Number of CPUs'
17
+ #c.long_desc 'Number of CPUs'
18
+ #c.flag [:c, :cpus]
19
+ #
20
+ #c.desc 'MB of RAM'
21
+ #c.long_desc 'MB of RAM'
22
+ #c.flag [:r, :ramMB]
23
+
24
+ c.desc 'Destination Machine IP Address'
25
+ c.long_desc 'Destination machine IP Address, when creating multiple vms ips will be calculated by incrementing this value'
26
+ c.flag :ip_address
27
+ c.action do |global_options,options,args|
28
+
29
+ ARGV.size >= 2 or abort "must specify VM target name and VM type"
30
+ vm_targets = ARGV.shift
31
+ vm_type = ARGV.shift
32
+ @logger.debug "Create invoked to create #{vm_targets} of type #{vm_type}\n\t#{global_options[:host]}\n\t#{options}\n\t#{args}."
33
+ Vmesh::template.has_key? vm_type.to_sym or raise "unknown machine type #{vm_type}, known types are #{Vmesh::template.keys.to_s}"
34
+
35
+ ip_address = options[:ip_address]
36
+ machine_options = {}
37
+ vm_manager = Vmesh::VSphere.new global_options
38
+ #default_vm_folder = vm_manager.get_folder(options[:folder]) if options[:folder]
39
+ default_vm_folder = options[:folder] || '/'
40
+ vm_targets.split(',').each do |vm_target|
41
+ machine_options[:ip_address] = ip_address if ip_address.to_s != ''
42
+ machine_options[:datastore] = options[:datastore] if options[:datastore].to_s != ''
43
+ machine_options[:memoryMB] = options[:ramMB] if options[:ramMB].to_s != ''
44
+ machine_options[:numCPUs] = options[:cpus] if options[:cpus].to_s != ''
45
+ new_vm = vm_manager.clone_machine(vm_type, vm_target, default_vm_folder, machine_options)
46
+ Vmesh.logger.info "#{vm_type}, #{vm_target}, #{machine_options}"
47
+ ip_address = IPAddr.new(ip_address).succ.to_s if ip_address.to_s != ''
48
+ Vmesh.logger.warn "Check #{vm_target}, nil vm returned..." if new_vm.nil?
49
+ end
50
+ end
51
+ end
52
+
53
+ module Vmesh
54
+ def self.parse_vm_target(vm_target)
55
+ vm_details = vm_target.match(/(.+)\/(.+)/)
56
+ vm = Hash.new
57
+ vm[:folder] = '/'
58
+ vm[:name] = vm_target
59
+ if vm_details
60
+ vm[:folder] = vm_details[1]
61
+ vm[:name] = vm_details[2]
62
+ end
63
+ vm
64
+ end
65
+ end
@@ -0,0 +1,6 @@
1
+ module CreateHelpers
2
+ def self.parse_vm_target (input_string)
3
+ puts "input_string"
4
+ end
5
+ end
6
+
@@ -0,0 +1,39 @@
1
+
2
+ desc 'list directory contents'
3
+ arg_name '[dir]'
4
+
5
+ command [:list,:ls,:dir] do |c|
6
+ c.desc 'list directory entries instead of contents, and do not dereference symbolic links'
7
+ c.switch [:d, :directory]
8
+
9
+ c.desc 'list recursively'
10
+ c.switch [:r, :recursive]
11
+
12
+ c.action do |global_options,options,args|
13
+ pwd = ARGV.shift if ARGV.any?
14
+ vm_manager = Vmesh::VSphere.new global_options
15
+ show_directories_only = options[:directory]
16
+ folder = pwd.nil? ? vm_manager.vm_root_folder : vm_manager.get_folder(pwd)
17
+ raise "Folder #{pwd} not found, exiting" if folder.to_s == ''
18
+ Vmesh::logger.debug "Searching folder #{folder.name}."
19
+ Vmesh::list_under folder,show_directories_only,options[:recursive],"/#{folder.name}"
20
+ end
21
+ end
22
+
23
+ module Vmesh
24
+ def self.list_under(folder, show_directories_only, recurse = false, currently_in = '')
25
+ currently_in = '' if currently_in == '/vm'
26
+ folder.childEntity.each do |x|
27
+ name = x.to_s.split('(').first
28
+ case name
29
+ when "Folder"
30
+ puts "#{currently_in}/#{x.name}/" #if show_directories_only
31
+ list_under(x, show_directories_only, recurse, "#{currently_in}/#{x.name}" ) if recurse
32
+ when "VirtualMachine"
33
+ puts "#{currently_in}/#{x.name}" unless show_directories_only
34
+ else
35
+ puts "# Unrecognized Entity " + x.to_s
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,19 @@
1
+
2
+ desc 'change the power state of the vm'
3
+ arg_name 'vm_name [on|off|reset|suspend|destroy]'
4
+
5
+ command :power do |c|
6
+ c.action do |global_options,options,args|
7
+ ARGV.size >= 2 or abort "must specify VM and a desired state."
8
+ vm_target = ARGV.shift
9
+ desired_state = ARGV.shift
10
+ abort "Invalid desired state #{desired_state}, valid ones are #{Vmesh::Machine::valid_states}." unless Vmesh::Machine::valid_states.include? desired_state
11
+ @logger.debug "Power invoked for #{vm_target} with desired state #{desired_state}\n\t#{global_options[:host]}\n\t#{options}\n\t#{args}."
12
+
13
+ vm_manager = Vmesh::VSphere.new global_options
14
+ vm = vm_manager.get_machine(vm_target, global_options[:datacenter])
15
+ Vmesh::logger.debug "Got vm #{vm.name}"
16
+
17
+ vm.power desired_state
18
+ end
19
+ end