esx 0.1.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/README.md +13 -9
  2. data/Rakefile +4 -1
  3. data/bin/esx +178 -43
  4. data/lib/esx.rb +182 -17
  5. metadata +112 -122
data/README.md CHANGED
@@ -12,11 +12,12 @@ If you want a full VMWare vSphere API ruby implementation have a look at https:/
12
12
 
13
13
  # Usage
14
14
 
15
- ESX ruby library includes a script to print ESX host information.
16
15
 
17
- Usage: esx my-esx-host-here
16
+ Usage: esx --help
18
17
 
19
- This will ask you for the username and password of the host.
18
+ ## Available Commands
19
+
20
+ __esx info --user root --password foo 10.10.0.2__
20
21
 
21
22
  Sample output:
22
23
 
@@ -27,14 +28,16 @@ Sample output:
27
28
  Memory Usage: 7429
28
29
  Cpu Cores: 8
29
30
  Power State: poweredOn
31
+ Hosted VMs: 2
32
+ Running VMs: 1
30
33
 
31
34
  Virtual Machines:
32
- +-------------------------+--------+------+------+-------+
33
- | NAME | MEMORY | CPUS | NICS | DISKS |
34
- +-------------------------+--------+------+------+-------+
35
- | foobar | 128 | 1 | 1 | 1 |
36
- | foobar2 | 256 | 2 | 1 | 1 |
37
- +-------------------------+--------+------+------+-------+
35
+ +-------------------------+--------+------+------+-------+------------+
36
+ | NAME | MEMORY | CPUS | NICS | DISKS | STATE |
37
+ +-------------------------+--------+------+------+-------+------------+
38
+ | foobar | 128 | 1 | 1 | 1 | poweredOn |
39
+ | foobar2 | 256 | 2 | 1 | 1 | poweredOff |
40
+ +-------------------------+--------+------+------+-------+------------+
38
41
 
39
42
  Datastores:
40
43
  +------------+--------------+--------------+-----------+------+---------------------------------------------------+
@@ -44,6 +47,7 @@ Sample output:
44
47
  | datastore1 | 141465485312 | 20716716032 | VMFS | true | /vmfs/volumes/4e6117e7-35c82a3e-ba79-5cf3fc9699c2 |
45
48
  +------------+--------------+--------------+-----------+------+---------------------------------------------------+
46
49
 
50
+ __esx create-vm --user root --password foo --name esx-rubiojr --disk-file /path/to/file.vmdk --datastore datastore1 --memory 2048 --poweron 10.10.0.2__
47
51
 
48
52
  # Using the library
49
53
 
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'rake'
3
- require 'lib/esx.rb'
3
+ require './lib/esx.rb'
4
4
 
5
5
  require 'jeweler'
6
6
  Jeweler::Tasks.new do |gem|
@@ -18,6 +18,9 @@ Jeweler::Tasks.new do |gem|
18
18
  gem.add_runtime_dependency 'alchemist'
19
19
  gem.add_runtime_dependency 'rbvmomi'
20
20
  gem.add_runtime_dependency 'terminal-table'
21
+ gem.add_runtime_dependency 'net-ssh'
22
+ gem.add_runtime_dependency 'net-scp'
23
+ gem.add_runtime_dependency 'clamp'
21
24
  # gem.add_development_dependency 'rspec', '> 1.2.3'
22
25
  end
23
26
  Jeweler::RubygemsDotOrgTasks.new
data/bin/esx CHANGED
@@ -2,61 +2,196 @@
2
2
  require 'rubygems'
3
3
  require 'esx'
4
4
  require 'terminal-table/import'
5
+ require 'clamp'
6
+ require 'net/http'
7
+ require 'fileutils'
5
8
 
6
- host_addr = ARGV[0]
7
-
8
- if host_addr.nil?
9
- $stderr.puts 'Usage: esx HOST'
10
- exit 1
9
+ class BaseCommand < Clamp::Command
10
+ parameter "ADDRESS", "ESX host address"
11
+ option "--user", "USER", "Username", :default => "root"
12
+ option "--password", "PASSWORD", "Password", :default => ""
13
+ option "--debug", :flag, "Print debugging info"
11
14
  end
12
15
 
13
- print "Username: "
14
- user = $stdin.gets.strip.chomp
16
+ class InfoCommand < BaseCommand
17
+
18
+ parameter "ADDRESS", "ESX host address"
19
+ option "--user", "USER", "Username", :default => "root"
20
+ option "--password", "PASSWORD", "Password", :default => ""
15
21
 
22
+ def execute
23
+ begin
16
24
 
17
- system "stty -echo"
18
- print "Password: "
19
- pass = $stdin.gets.strip.chomp
20
- system "stty echo"
21
- puts
25
+ host = ESX::Host.connect(address, user, password)
22
26
 
23
- begin
27
+ puts
28
+ name = host.name.upcase
29
+ puts "*" * name.size
30
+ puts name
31
+ puts "*" * name.size
32
+ puts "Memory Size: %s GB" % host.memory_size.bytes.to.gigabytes.to_f.round
33
+ puts "Memory Usage: %s GB" % host.memory_usage.bytes.to.gigabytes.to_f.round
34
+ puts "Cpu Cores: %s" % host.cpu_cores
35
+ puts "Power State: %s" % host.power_state
36
+ puts "Hosted VMs: %s" % host.virtual_machines.size
37
+ puts "Running VMs: %s" % (host.virtual_machines.find_all{ |vm| vm.power_state == 'poweredOn' }).size
24
38
 
25
- host = ESX::Host.connect(host_addr, user, pass)
39
+ if not host.virtual_machines.empty?
40
+ puts "\nVirtual Machines:"
41
+ user_table = table do |t|
42
+ t.headings = "NAME","MEMORY","CPUS","NICS","DISKS", "STATE"
43
+ host.virtual_machines.each do |vm|
44
+ t << [vm.name,vm.memory_size.bytes.to.megabytes.to_i, vm.cpus, vm.ethernet_cards_number, vm.virtual_disks_number, vm.power_state]
45
+ end
46
+ end
47
+ puts user_table
48
+ end
49
+
50
+ puts "\nDatastores:"
51
+ user_table = table do |t|
52
+ t.headings = "NAME","CAPACITY","FREESPACE","ACCESIBLE","TYPE","URL"
53
+ host.datastores.each do |ds|
54
+ dsname = ds.name
55
+ if dsname.size > 20
56
+ dsname = dsname[0..19] + '...'
57
+ end
58
+ t << [dsname,ds.capacity, ds.free_space, ds.datastore_type, ds.accessible, ds.url]
59
+ end
60
+ end
61
+ puts user_table
62
+ puts
26
63
 
27
- puts
28
- name = host.name.upcase
29
- puts "*" * name.size
30
- puts name
31
- puts "*" * name.size
32
- puts "Memory Size: %s" % host.memory_size.bytes.to.megabytes.to_i
33
- puts "Memory Usage: %s" % host.memory_usage.bytes.to.megabytes.to_i
34
- puts "Cpu Cores: %s" % host.cpu_cores
35
- puts "Power State: %s" % host.power_state
36
- puts "\nVirtual Machines:"
37
- user_table = table do |t|
38
- t.headings = "NAME","MEMORY","CPUS","NICS","DISKS"
39
- host.virtual_machines.each do |vm|
40
- t << [vm.name,vm.memory_size.bytes.to.megabytes.to_i, vm.cpus, vm.ethernet_cards_number, vm.virtual_disks_number]
64
+ rescue Exception => e
65
+ puts "Error connecting to the ESX host"
66
+ puts "\n#{e.message}"
67
+ if debug?
68
+ puts e.backtrace
69
+ end
41
70
  end
42
71
  end
43
- puts user_table
44
- puts "\nDatastores:"
45
- user_table = table do |t|
46
- t.headings = "NAME","CAPACITY","FREESPACE","ACCESIBLE","TYPE","URL"
47
- host.datastores.each do |ds|
48
- dsname = ds.name
49
- if dsname.size > 20
50
- dsname = dsname[0..19] + '...'
72
+ end
73
+
74
+ class CreateVMCommand < BaseCommand
75
+
76
+ parameter "ADDRESS", "ESX host address"
77
+ option "--disk-file", "DISK_FILE", "VMDK file to import", :attribute_name => :disk_file
78
+ option "--guest-id", "GUEST_ID", "GuestID value", :attribute_name => :guest_id, :default => 'otherGuest'
79
+ option "--name", "VM NAME", "Virtual Machine name (required)"
80
+ option "--memory", "MEMORY", "VM Memory size in MB", :default => 512
81
+ option "--tmpdir", "TMP DIR", "tmp dir used to download files", :default => "/tmp"
82
+ option "--datastore", "DATASTORE", "Datastore used to host the disk", :default => "datastore1"
83
+ option "--poweron", :flag, "Power on the VM after creation"
84
+
85
+ def execute
86
+ begin
87
+ host = ESX::Host.connect address, user, password
88
+ rescue Exception => e
89
+ $stderr.puts "Can't connect to the host #{address}."
90
+ if debug?
91
+ $stderr.puts e.message
92
+ end
93
+ exit 1
94
+ end
95
+ downloaded_file = nil
96
+ df = disk_file.dup
97
+ if df.strip.chomp =~ /^http/
98
+ begin
99
+ downloaded_file = disk_file.dup
100
+ tmpfile = "#{tmpdir}/#{Time.now.to_i}.esx"
101
+ puts "Downloading file... (#{tmpfile})"
102
+ download! downloaded_file, tmpfile
103
+ puts
104
+ df = tmpfile
105
+ rescue Exception => e
106
+ FileUtils.rm_f(tmpfile)
107
+ $stderr.puts "Error downloading file from #{downloaded_file}."
108
+ $stderr.puts e.message if debug?
109
+ exit 1
51
110
  end
52
- t << [dsname,ds.capacity, ds.free_space, ds.datastore_type, ds.accessible, ds.url]
53
111
  end
112
+ raise Exception.new("Invalid disk file") if not File.exist?(df)
113
+ if not name
114
+ $stderr.puts "Invalid VM name."
115
+ $stderr.puts "Use --name option to specify the VM name"
116
+ exit 1
117
+ end
118
+ host.remote_command "mkdir /vmfs/volumes/#{datastore}/#{name}"
119
+
120
+ begin
121
+ host.import_disk df, "/vmfs/volumes/#{datastore}/#{name}/#{name}.vmdk"
122
+ rescue Exception => e
123
+ $stderr.puts "Error uploading file to /vmfs/volumes/#{datastore}/#{name}/#{name}.vmdk"
124
+ $stderr.puts e.message if debug?
125
+ exit 1
126
+ end
127
+
128
+ if not downloaded_file.nil?
129
+ puts "Deleting tmp file #{df}" if debug?
130
+ FileUtils.rm_f(df)
131
+ end
132
+ vm = host.create_vm :vm_name => name,
133
+ :disk_file => "#{name}/#{name}.vmdk",
134
+ :datastore => datastore, :disk_type => :flat, :memory => memory,
135
+ :guest_id => guest_id
136
+ if poweron?
137
+ vm.power_on
138
+ end
139
+ end
140
+
141
+ def report_progress(progress, total, show_parts=true)
142
+ line_reset = "\r\e[0K"
143
+ percent = (progress.to_f / total.to_f) * 100
144
+ line = "Progress: #{percent.to_i}%"
145
+ line << " (#{progress} / #{total})" if show_parts
146
+ line = "#{line_reset}#{line}"
147
+ $stdout.sync = true
148
+ $stdout.print line
149
+ end
150
+
151
+ def download!(source_url, destination_file)
152
+ dst = File.open(destination_file, 'w')
153
+ proxy_uri = URI.parse(ENV["http_proxy"] || "")
154
+ uri = URI.parse(source_url)
155
+ http = Net::HTTP.new(uri.host, uri.port, proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
156
+
157
+ if uri.scheme == "https"
158
+ http.use_ssl = true
159
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
160
+ end
161
+
162
+ res = http.start do |h|
163
+ h.request_get(uri.request_uri) do |response|
164
+ total = response.content_length
165
+ progress = 0
166
+ segment_count = 0
167
+
168
+ response.read_body do |segment|
169
+ # Report the progress out
170
+ progress += segment.length
171
+ segment_count += 1
172
+
173
+ # Progress reporting is limited to every 25 segments just so
174
+ # we're not constantly updating
175
+ if segment_count % 25 == 0
176
+ report_progress(progress, total)
177
+ segment_count = 0
178
+ end
179
+ # Store the segment
180
+ dst.write(segment)
181
+ end
182
+ end
183
+ end
184
+
185
+ raise Exception.new("HTTP Error #{res}") if res.class != Net::HTTPOK
186
+ ensure
187
+ dst.close
54
188
  end
55
- puts user_table
56
- puts
57
189
 
58
- rescue Exception => e
59
- puts "Error connecting to the ESX host"
60
- puts "\n#{e.message}"
61
- puts e.backtrace
62
190
  end
191
+
192
+ class DefaultCommand < Clamp::Command
193
+ default_subcommand "info", "Display host info", InfoCommand
194
+ subcommand "create-vm", "Create a VM", CreateVMCommand
195
+ end
196
+
197
+ DefaultCommand.run
data/lib/esx.rb CHANGED
@@ -1,12 +1,23 @@
1
1
  require 'rubygems'
2
2
  require 'rbvmomi'
3
3
  require 'alchemist'
4
+ require 'net/scp'
5
+ require 'net/ssh'
4
6
 
5
7
  module ESX
6
- VERSION = '0.1.1'
8
+
9
+ VERSION = '0.2'
7
10
 
8
11
  class Host
9
12
 
13
+ attr_reader :address, :user, :password
14
+
15
+ def initialize(address, user, password)
16
+ @address = address
17
+ @password = password
18
+ @user = user
19
+ end
20
+
10
21
  # Connect to a ESX host
11
22
  #
12
23
  # Requires hostname/ip, username and password
@@ -14,7 +25,7 @@ module ESX
14
25
  # Host connection is insecure by default
15
26
  def self.connect(host, user, password, insecure=true)
16
27
  vim = RbVmomi::VIM.connect :host => host, :user => user, :password => password, :insecure => insecure
17
- host = Host.new
28
+ host = Host.new(host, user,password)
18
29
  host.vim = vim
19
30
  host
20
31
  end
@@ -77,6 +88,8 @@ module ESX
77
88
  # :disk_size => 4096, #(in MB, optional)
78
89
  # :memory => 128, #(in MB, optional)
79
90
  # :datastore => datastore1 #(string, optional)
91
+ # :disk_file => path to vmdk inside datastore (optional)
92
+ # :disk_type => flat, sparse (default flat)
80
93
  # }
81
94
  #
82
95
  # Default values above.
@@ -98,7 +111,7 @@ module ESX
98
111
  vm_cfg = {
99
112
  :name => spec[:vm_name],
100
113
  :guestId => spec[:guest_id],
101
- :files => { :vmPathName => '[datastore1]' },
114
+ :files => { :vmPathName => spec[:datastore] },
102
115
  :numCPUs => spec[:cpus],
103
116
  :memoryMB => spec[:memory],
104
117
  :deviceChange => [
@@ -109,19 +122,6 @@ module ESX
109
122
  :busNumber => 0,
110
123
  :sharedBus => :noSharing)
111
124
  },
112
- {
113
- :operation => :add,
114
- :fileOperation => :create,
115
- :device => RbVmomi::VIM.VirtualDisk(
116
- :key => 0,
117
- :backing => RbVmomi::VIM.VirtualDiskFlatVer2BackingInfo(
118
- :fileName => spec[:datastore],
119
- :diskMode => :persistent,
120
- :thinProvisioned => true),
121
- :controllerKey => 1000,
122
- :unitNumber => 0,
123
- :capacityInKB => spec[:disk_size])
124
- },
125
125
  {
126
126
  :operation => :add,
127
127
  :device => RbVmomi::VIM.VirtualE1000(
@@ -143,6 +143,10 @@ module ESX
143
143
  }
144
144
  ]
145
145
  }
146
+ vm_cfg[:deviceChange].push(create_disk_spec(:disk_file => spec[:disk_file],
147
+ :disk_type => spec[:disk_type],
148
+ :disk_size => spec[:disk_size],
149
+ :datastore => spec[:datastore]))
146
150
  VM.wrap(@_datacenter.vmFolder.CreateVM_Task(:config => vm_cfg, :pool => @_datacenter.hostFolder.children.first.resourcePool).wait_for_completion)
147
151
  end
148
152
 
@@ -172,6 +176,97 @@ module ESX
172
176
  vms
173
177
  end
174
178
 
179
+ #
180
+ # Run a command in the ESX host via SSH
181
+ #
182
+ def remote_command(cmd)
183
+ Net::SSH.start(@address, @user, :password => @password) do |ssh|
184
+ ssh.exec! cmd
185
+ end
186
+ end
187
+
188
+ #
189
+ # Upload file
190
+ #
191
+ def upload_file(source, dest, print_progress = true)
192
+ Net::SSH.start(@address, @user, :password => @password) do |ssh|
193
+ puts "Uploading file... (#{File.basename(source)})"
194
+ ssh.scp.upload!(source, dest) do |ch, name, sent, total|
195
+ if print_progress
196
+ print "\rProgress: #{(sent.to_f * 100 / total.to_f).to_i}% completed"
197
+ end
198
+ end
199
+ end
200
+ puts if print_progress
201
+ end
202
+
203
+ def import_disk(source, destination, print_progress = true)
204
+ tmp_dest = destination + ".tmp"
205
+ Net::SSH.start(@address, @user, :password => @password) do |ssh|
206
+ if not (ssh.exec! "ls #{destination} 2>/dev/null").nil?
207
+ raise Exception.new("Destination file #{destination} already exists")
208
+ end
209
+ puts "Uploading file... (#{File.basename(source)})"
210
+ ssh.scp.upload!(source, tmp_dest) do |ch, name, sent, total|
211
+ if print_progress
212
+ print "\rProgress: #{(sent.to_f * 100 / total.to_f).to_i}%"
213
+ end
214
+ end
215
+ if print_progress
216
+ puts "\nConverting disk..."
217
+ ssh.exec "vmkfstools -i #{tmp_dest} --diskformat thin #{destination}; rm -f #{tmp_dest}"
218
+ else
219
+ ssh.exec "vmkfstools -i #{tmp_dest} --diskformat thin #{destination} >/dev/null 2>&1; rm -f #{tmp_dest}"
220
+ end
221
+ end
222
+ puts
223
+ end
224
+
225
+ private
226
+ #
227
+ # disk_file
228
+ # datastore
229
+ # disk_size
230
+ # disk_type
231
+ #
232
+ def create_disk_spec(params)
233
+ disk_type = params[:disk_type] || :flat
234
+ disk_file = params[:disk_file]
235
+ if disk_type == :sparse and disk_file.nil?
236
+ raise Exception.new("Creating sparse disks in ESX is not supported. Use an existing image.")
237
+ end
238
+ disk_size = params[:disk_size]
239
+ datastore = params[:datastore]
240
+ datastore = datastore + " #{disk_file}" if not disk_file.nil?
241
+ spec = {}
242
+ if disk_type == :sparse
243
+ spec = {
244
+ :operation => :add,
245
+ :device => RbVmomi::VIM.VirtualDisk(
246
+ :key => 0,
247
+ :backing => RbVmomi::VIM.VirtualDiskSparseVer2BackingInfo(
248
+ :fileName => datastore,
249
+ :diskMode => :persistent),
250
+ :controllerKey => 1000,
251
+ :unitNumber => 0,
252
+ :capacityInKB => disk_size)
253
+ }
254
+ else
255
+ spec = {
256
+ :operation => :add,
257
+ :device => RbVmomi::VIM.VirtualDisk(
258
+ :key => 0,
259
+ :backing => RbVmomi::VIM.VirtualDiskFlatVer2BackingInfo(
260
+ :fileName => datastore,
261
+ :diskMode => :persistent),
262
+ :controllerKey => 1000,
263
+ :unitNumber => 0,
264
+ :capacityInKB => disk_size)
265
+ }
266
+ end
267
+ spec[:fileOperation] = :create if disk_file.nil?
268
+ spec
269
+ end
175
270
  end
176
271
 
177
272
  class VM
@@ -231,19 +326,84 @@ module ESX
231
326
  vm_object.Destroy_Task.wait_for_completion
232
327
  end
233
328
 
329
+ def guest_info
330
+ GuestInfo.wrap(vm_object.guest)
331
+ end
332
+
333
+ #
334
+ # Shortcut to GuestInfo.ip_address
335
+ #
336
+ def ip_address
337
+ guest_info.ip_address
338
+ end
339
+
340
+ end
341
+
342
+ class NetworkInterface
343
+
344
+ attr_accessor :_wrapped_object
345
+
346
+ def self.wrap(obj)
347
+ ni = NetworkInterface.new
348
+ ni._wrapped_object = obj
349
+ ni
350
+ end
351
+
352
+ def ip_address
353
+ _wrapped_object.ipAddress.first
354
+ end
355
+
356
+ def mac
357
+ _wrapped_object.ipAddress.last
358
+ end
359
+
360
+ end
361
+
362
+ class GuestInfo
363
+
364
+ attr_accessor :_wrapped_object
365
+
366
+ def self.wrap(obj)
367
+ gi = GuestInfo.new
368
+ gi._wrapped_object = obj
369
+ gi
370
+ end
371
+
372
+ def ip_address
373
+ _wrapped_object.ipAddress
374
+ end
375
+
376
+ def nics
377
+ n = []
378
+ _wrapped_object.net.each do |nic|
379
+ n << NetworkInterface.wrap(nic)
380
+ end
381
+ n
382
+ end
383
+
384
+ def tools_running_status
385
+ _wrapped_object.toolsRunningStatus
386
+ end
387
+
388
+ def vmware_tools_installed?
389
+ _wrapped_object.toolsRunningStatus != 'guestToolsNotRunning'
390
+ end
391
+
234
392
  end
235
393
 
236
394
  class Datastore
237
395
 
238
396
  attr_accessor :name, :capacity, :datastore_type, :free_space, :accessible
239
397
  attr_accessor :url
398
+ # Internal use only
399
+ attr_accessor :_wrapped_object
240
400
 
241
401
  #
242
402
  # Internal method. Do not use
243
403
  #
244
404
  def self.wrap(ds)
245
- @_datastore = ds
246
405
  _ds = Datastore.new
406
+ _ds._wrapped_object = ds
247
407
  _ds.name = ds.summary.name
248
408
  _ds.capacity = ds.summary.capacity
249
409
  _ds.free_space = ds.summary.freeSpace
@@ -252,5 +412,10 @@ module ESX
252
412
  _ds.url = ds.summary.url
253
413
  _ds
254
414
  end
415
+
416
+ def method_missing(name, *args)
417
+ @_wrapped_object.send name, *args
418
+ end
419
+
255
420
  end
256
421
  end
metadata CHANGED
@@ -1,134 +1,135 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: esx
3
- version: !ruby/object:Gem::Version
4
- hash: 25
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.2'
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 1
10
- version: 0.1.1
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Sergio Rubio
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-09-06 00:00:00 Z
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
21
- requirement: &id001 !ruby/object:Gem::Requirement
22
- none: false
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- hash: 3
27
- segments:
28
- - 0
29
- version: "0"
30
- version_requirements: *id001
12
+ date: 2011-10-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
31
15
  name: shoulda
32
- prerelease: false
16
+ requirement: &8606860 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
33
22
  type: :development
34
- - !ruby/object:Gem::Dependency
35
- requirement: &id002 !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ version_requirements: *8606860
25
+ - !ruby/object:Gem::Dependency
26
+ name: bundler
27
+ requirement: &8620220 !ruby/object:Gem::Requirement
36
28
  none: false
37
- requirements:
29
+ requirements:
38
30
  - - ~>
39
- - !ruby/object:Gem::Version
40
- hash: 23
41
- segments:
42
- - 1
43
- - 0
44
- - 0
31
+ - !ruby/object:Gem::Version
45
32
  version: 1.0.0
46
- version_requirements: *id002
47
- name: bundler
48
- prerelease: false
49
33
  type: :development
50
- - !ruby/object:Gem::Dependency
51
- requirement: &id003 !ruby/object:Gem::Requirement
34
+ prerelease: false
35
+ version_requirements: *8620220
36
+ - !ruby/object:Gem::Dependency
37
+ name: jeweler
38
+ requirement: &8618780 !ruby/object:Gem::Requirement
52
39
  none: false
53
- requirements:
40
+ requirements:
54
41
  - - ~>
55
- - !ruby/object:Gem::Version
56
- hash: 7
57
- segments:
58
- - 1
59
- - 5
60
- - 2
42
+ - !ruby/object:Gem::Version
61
43
  version: 1.5.2
62
- version_requirements: *id003
63
- name: jeweler
64
- prerelease: false
65
44
  type: :development
66
- - !ruby/object:Gem::Dependency
67
- requirement: &id004 !ruby/object:Gem::Requirement
68
- none: false
69
- requirements:
70
- - - ">="
71
- - !ruby/object:Gem::Version
72
- hash: 3
73
- segments:
74
- - 0
75
- version: "0"
76
- version_requirements: *id004
77
- name: rcov
78
45
  prerelease: false
79
- type: :development
80
- - !ruby/object:Gem::Dependency
81
- requirement: &id005 !ruby/object:Gem::Requirement
46
+ version_requirements: *8618780
47
+ - !ruby/object:Gem::Dependency
48
+ name: rcov
49
+ requirement: &8617480 !ruby/object:Gem::Requirement
82
50
  none: false
83
- requirements:
84
- - - ">="
85
- - !ruby/object:Gem::Version
86
- hash: 3
87
- segments:
88
- - 0
89
- version: "0"
90
- version_requirements: *id005
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *8617480
58
+ - !ruby/object:Gem::Dependency
91
59
  name: alchemist
60
+ requirement: &8615740 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
92
67
  prerelease: false
68
+ version_requirements: *8615740
69
+ - !ruby/object:Gem::Dependency
70
+ name: rbvmomi
71
+ requirement: &8614480 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
93
77
  type: :runtime
94
- - !ruby/object:Gem::Dependency
95
- requirement: &id006 !ruby/object:Gem::Requirement
78
+ prerelease: false
79
+ version_requirements: *8614480
80
+ - !ruby/object:Gem::Dependency
81
+ name: terminal-table
82
+ requirement: &8631960 !ruby/object:Gem::Requirement
96
83
  none: false
97
- requirements:
98
- - - ">="
99
- - !ruby/object:Gem::Version
100
- hash: 3
101
- segments:
102
- - 0
103
- version: "0"
104
- version_requirements: *id006
105
- name: rbvmomi
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :runtime
106
89
  prerelease: false
90
+ version_requirements: *8631960
91
+ - !ruby/object:Gem::Dependency
92
+ name: net-ssh
93
+ requirement: &8630540 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
107
99
  type: :runtime
108
- - !ruby/object:Gem::Dependency
109
- requirement: &id007 !ruby/object:Gem::Requirement
100
+ prerelease: false
101
+ version_requirements: *8630540
102
+ - !ruby/object:Gem::Dependency
103
+ name: net-scp
104
+ requirement: &8629100 !ruby/object:Gem::Requirement
110
105
  none: false
111
- requirements:
112
- - - ">="
113
- - !ruby/object:Gem::Version
114
- hash: 3
115
- segments:
116
- - 0
117
- version: "0"
118
- version_requirements: *id007
119
- name: terminal-table
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :runtime
120
111
  prerelease: false
112
+ version_requirements: *8629100
113
+ - !ruby/object:Gem::Dependency
114
+ name: clamp
115
+ requirement: &8627300 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
121
  type: :runtime
122
+ prerelease: false
123
+ version_requirements: *8627300
122
124
  description: Manage VMWare ESX hosts with ease
123
125
  email: rubiojr@frameos.org
124
- executables:
126
+ executables:
125
127
  - esx
126
128
  extensions: []
127
-
128
- extra_rdoc_files:
129
+ extra_rdoc_files:
129
130
  - LICENSE.txt
130
131
  - README.md
131
- files:
132
+ files:
132
133
  - .document
133
134
  - Gemfile
134
135
  - LICENSE.txt
@@ -140,39 +141,28 @@ files:
140
141
  - test/helper.rb
141
142
  - test/test_esx.rb
142
143
  homepage: http://github.com/rubiojr/esx
143
- licenses:
144
+ licenses:
144
145
  - MIT
145
146
  post_install_message:
146
147
  rdoc_options: []
147
-
148
- require_paths:
148
+ require_paths:
149
149
  - lib
150
- required_ruby_version: !ruby/object:Gem::Requirement
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
151
  none: false
152
- requirements:
153
- - - ">="
154
- - !ruby/object:Gem::Version
155
- hash: 3
156
- segments:
157
- - 0
158
- version: "0"
159
- required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ! '>='
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
157
  none: false
161
- requirements:
162
- - - ">="
163
- - !ruby/object:Gem::Version
164
- hash: 3
165
- segments:
166
- - 0
167
- version: "0"
158
+ requirements:
159
+ - - ! '>='
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
168
162
  requirements: []
169
-
170
163
  rubyforge_project:
171
- rubygems_version: 1.7.2
164
+ rubygems_version: 1.8.10
172
165
  signing_key:
173
166
  specification_version: 3
174
167
  summary: Simple RbVmomi wrapper library to manage VMWare ESX hosts
175
- test_files:
176
- - examples/basics.rb
177
- - test/helper.rb
178
- - test/test_esx.rb
168
+ test_files: []