esx 0.1.1 → 0.2

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.
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: []