vmpooler 0.13.1 → 0.14.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.
- checksums.yaml +4 -4
- data/bin/vmpooler +15 -10
- data/lib/vmpooler.rb +4 -16
- data/lib/vmpooler/api.rb +41 -34
- data/lib/vmpooler/api/helpers.rb +1 -1
- data/lib/vmpooler/api/request_logger.rb +20 -0
- data/lib/vmpooler/api/v1.rb +52 -27
- data/lib/vmpooler/generic_connection_pool.rb +7 -5
- data/lib/vmpooler/metrics.rb +24 -0
- data/lib/vmpooler/metrics/dummy_statsd.rb +24 -0
- data/lib/vmpooler/metrics/graphite.rb +47 -0
- data/lib/vmpooler/metrics/promstats.rb +380 -0
- data/lib/vmpooler/metrics/promstats/collector_middleware.rb +121 -0
- data/lib/vmpooler/metrics/statsd.rb +40 -0
- data/lib/vmpooler/pool_manager.rb +32 -40
- data/lib/vmpooler/providers/dummy.rb +2 -1
- data/lib/vmpooler/providers/vsphere.rb +88 -25
- data/lib/vmpooler/util/parsing.rb +16 -0
- data/lib/vmpooler/version.rb +1 -1
- metadata +25 -6
- data/lib/vmpooler/dummy_statsd.rb +0 -22
- data/lib/vmpooler/graphite.rb +0 -42
- data/lib/vmpooler/statsd.rb +0 -37
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This is an adapted Collector module for vmpooler based on the sample implementation
|
4
|
+
# available in the prometheus client_ruby library
|
5
|
+
# https://github.com/prometheus/client_ruby/blob/master/lib/prometheus/middleware/collector.rb
|
6
|
+
#
|
7
|
+
# The code was also failing Rubocop on PR check, so have addressed all the offenses.
|
8
|
+
#
|
9
|
+
# The method strip_hostnames_from_path (originally strip_ids_from_path) has been adapted
|
10
|
+
# to add a match for hostnames in paths # to replace with a single ":hostname" string to
|
11
|
+
# avoid # proliferation of stat lines for # each new vm hostname deleted, modified or
|
12
|
+
# otherwise queried.
|
13
|
+
|
14
|
+
require 'benchmark'
|
15
|
+
require 'prometheus/client'
|
16
|
+
require 'vmpooler/logger'
|
17
|
+
|
18
|
+
module Vmpooler
|
19
|
+
class Metrics
|
20
|
+
class Promstats
|
21
|
+
# CollectorMiddleware is an implementation of Rack Middleware customised
|
22
|
+
# for vmpooler use.
|
23
|
+
#
|
24
|
+
# By default metrics are registered on the global registry. Set the
|
25
|
+
# `:registry` option to use a custom registry.
|
26
|
+
#
|
27
|
+
# By default metrics all have the prefix "http_server". Set to something
|
28
|
+
# else if you like.
|
29
|
+
#
|
30
|
+
# The request counter metric is broken down by code, method and path by
|
31
|
+
# default. Set the `:counter_label_builder` option to use a custom label
|
32
|
+
# builder.
|
33
|
+
#
|
34
|
+
# The request duration metric is broken down by method and path by default.
|
35
|
+
# Set the `:duration_label_builder` option to use a custom label builder.
|
36
|
+
#
|
37
|
+
# Label Builder functions will receive a Rack env and a status code, and must
|
38
|
+
# return a hash with the labels for that request. They must also accept an empty
|
39
|
+
# env, and return a hash with the correct keys. This is necessary to initialize
|
40
|
+
# the metrics with the correct set of labels.
|
41
|
+
class CollectorMiddleware
|
42
|
+
attr_reader :app, :registry
|
43
|
+
|
44
|
+
def initialize(app, options = {})
|
45
|
+
@app = app
|
46
|
+
@registry = options[:registry] || Prometheus::Client.registry
|
47
|
+
@metrics_prefix = options[:metrics_prefix] || 'http_server'
|
48
|
+
|
49
|
+
init_request_metrics
|
50
|
+
init_exception_metrics
|
51
|
+
end
|
52
|
+
|
53
|
+
def call(env) # :nodoc:
|
54
|
+
trace(env) { @app.call(env) }
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
def init_request_metrics
|
60
|
+
@requests = @registry.counter(
|
61
|
+
:"#{@metrics_prefix}_requests_total",
|
62
|
+
docstring:
|
63
|
+
'The total number of HTTP requests handled by the Rack application.',
|
64
|
+
labels: %i[code method path]
|
65
|
+
)
|
66
|
+
@durations = @registry.histogram(
|
67
|
+
:"#{@metrics_prefix}_request_duration_seconds",
|
68
|
+
docstring: 'The HTTP response duration of the Rack application.',
|
69
|
+
labels: %i[method path]
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
def init_exception_metrics
|
74
|
+
@exceptions = @registry.counter(
|
75
|
+
:"#{@metrics_prefix}_exceptions_total",
|
76
|
+
docstring: 'The total number of exceptions raised by the Rack application.',
|
77
|
+
labels: [:exception]
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
def trace(env)
|
82
|
+
response = nil
|
83
|
+
duration = Benchmark.realtime { response = yield }
|
84
|
+
record(env, response.first.to_s, duration)
|
85
|
+
response
|
86
|
+
rescue StandardError => e
|
87
|
+
@exceptions.increment(labels: { exception: e.class.name })
|
88
|
+
raise
|
89
|
+
end
|
90
|
+
|
91
|
+
def record(env, code, duration)
|
92
|
+
counter_labels = {
|
93
|
+
code: code,
|
94
|
+
method: env['REQUEST_METHOD'].downcase,
|
95
|
+
path: strip_hostnames_from_path(env['PATH_INFO'])
|
96
|
+
}
|
97
|
+
|
98
|
+
duration_labels = {
|
99
|
+
method: env['REQUEST_METHOD'].downcase,
|
100
|
+
path: strip_hostnames_from_path(env['PATH_INFO'])
|
101
|
+
}
|
102
|
+
|
103
|
+
@requests.increment(labels: counter_labels)
|
104
|
+
@durations.observe(duration, labels: duration_labels)
|
105
|
+
rescue # rubocop:disable Style/RescueStandardError
|
106
|
+
nil
|
107
|
+
end
|
108
|
+
|
109
|
+
def strip_hostnames_from_path(path)
|
110
|
+
# Custom for /vm path - so we just collect aggrate stats for all usage along this one
|
111
|
+
# path. Custom counters are then added more specific endpoints in v1.rb
|
112
|
+
# Since we aren't parsing UID/GIDs as in the original example, these are removed.
|
113
|
+
# Similarly, request IDs are also stripped from the /ondemand path.
|
114
|
+
path
|
115
|
+
.gsub(%r{/vm/.+$}, '/vm')
|
116
|
+
.gsub(%r{/ondemand/.+$}, '/ondemand')
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubygems' unless defined?(Gem)
|
4
|
+
require 'statsd'
|
5
|
+
|
6
|
+
module Vmpooler
|
7
|
+
class Metrics
|
8
|
+
class Statsd < Metrics
|
9
|
+
attr_reader :server, :port, :prefix
|
10
|
+
|
11
|
+
def initialize(logger, params = {})
|
12
|
+
raise ArgumentError, "Statsd server is required. Config: #{params.inspect}" if params['server'].nil? || params['server'].empty?
|
13
|
+
|
14
|
+
host = params['server']
|
15
|
+
@port = params['port'] || 8125
|
16
|
+
@prefix = params['prefix'] || 'vmpooler'
|
17
|
+
@server = ::Statsd.new(host, @port)
|
18
|
+
@logger = logger
|
19
|
+
end
|
20
|
+
|
21
|
+
def increment(label)
|
22
|
+
server.increment(prefix + '.' + label)
|
23
|
+
rescue StandardError => e
|
24
|
+
@logger.log('s', "[!] Failure incrementing #{prefix}.#{label} on statsd server [#{server}:#{port}]: #{e}")
|
25
|
+
end
|
26
|
+
|
27
|
+
def gauge(label, value)
|
28
|
+
server.gauge(prefix + '.' + label, value)
|
29
|
+
rescue StandardError => e
|
30
|
+
@logger.log('s', "[!] Failure updating gauge #{prefix}.#{label} on statsd server [#{server}:#{port}]: #{e}")
|
31
|
+
end
|
32
|
+
|
33
|
+
def timing(label, duration)
|
34
|
+
server.timing(prefix + '.' + label, duration)
|
35
|
+
rescue StandardError => e
|
36
|
+
@logger.log('s', "[!] Failure updating timing #{prefix}.#{label} on statsd server [#{server}:#{port}]: #{e}")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'vmpooler/providers'
|
4
|
+
require 'vmpooler/util/parsing'
|
4
5
|
require 'spicy-proton'
|
5
6
|
require 'resolv' # ruby standard lib
|
6
7
|
|
@@ -149,8 +150,11 @@ module Vmpooler
|
|
149
150
|
redis.pipelined do
|
150
151
|
redis.hset("vmpooler__active__#{pool}", vm, Time.now)
|
151
152
|
redis.hset("vmpooler__vm__#{vm}", 'checkout', Time.now)
|
152
|
-
|
153
|
-
|
153
|
+
if ondemandrequest_hash['token:token']
|
154
|
+
redis.hset("vmpooler__vm__#{vm}", 'token:token', ondemandrequest_hash['token:token'])
|
155
|
+
redis.hset("vmpooler__vm__#{vm}", 'token:user', ondemandrequest_hash['token:user'])
|
156
|
+
redis.hset("vmpooler__vm__#{vm}", 'lifetime', $config[:config]['vm_lifetime_auth'].to_i)
|
157
|
+
end
|
154
158
|
redis.sadd("vmpooler__#{request_id}__#{pool_alias}__#{pool}", vm)
|
155
159
|
end
|
156
160
|
move_vm_queue(pool, vm, 'pending', 'running', redis)
|
@@ -490,15 +494,21 @@ module Vmpooler
|
|
490
494
|
return if checkout.nil?
|
491
495
|
|
492
496
|
user ||= 'unauthenticated'
|
493
|
-
|
494
|
-
|
495
|
-
|
497
|
+
user = user.gsub('.', '_')
|
498
|
+
$metrics.increment("user.#{user}.#{poolname}")
|
499
|
+
|
500
|
+
return unless jenkins_build_url
|
501
|
+
|
502
|
+
if jenkins_build_url.include? 'litmus'
|
503
|
+
# Very simple filter for Litmus jobs - just count them coming through for the moment.
|
504
|
+
$metrics.increment("usage_litmus.#{user}.#{poolname}")
|
496
505
|
return
|
497
506
|
end
|
498
507
|
|
499
508
|
url_parts = jenkins_build_url.split('/')[2..-1]
|
500
|
-
|
509
|
+
jenkins_instance = url_parts[0].gsub('.', '_')
|
501
510
|
value_stream_parts = url_parts[2].split('_')
|
511
|
+
value_stream_parts = value_stream_parts.map { |s| s.gsub('.', '_') }
|
502
512
|
value_stream = value_stream_parts.shift
|
503
513
|
branch = value_stream_parts.pop
|
504
514
|
project = value_stream_parts.shift
|
@@ -506,22 +516,9 @@ module Vmpooler
|
|
506
516
|
build_metadata_parts = url_parts[3]
|
507
517
|
component_to_test = component_to_test('RMM_COMPONENT_TO_TEST_NAME', build_metadata_parts)
|
508
518
|
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
instance,
|
513
|
-
value_stream,
|
514
|
-
branch,
|
515
|
-
project,
|
516
|
-
job_name,
|
517
|
-
component_to_test,
|
518
|
-
poolname
|
519
|
-
]
|
520
|
-
|
521
|
-
metric_parts = metric_parts.reject(&:nil?)
|
522
|
-
metric_parts = metric_parts.map { |s| s.gsub('.', '_') }
|
523
|
-
|
524
|
-
$metrics.increment(metric_parts.join('.'))
|
519
|
+
$metrics.increment("usage_jenkins_instance.#{jenkins_instance}.#{value_stream}.#{poolname}")
|
520
|
+
$metrics.increment("usage_branch_project.#{branch}.#{project}.#{poolname}")
|
521
|
+
$metrics.increment("usage_job_component.#{job_name}.#{component_to_test}.#{poolname}")
|
525
522
|
rescue StandardError => e
|
526
523
|
$logger.log('d', "[!] [#{poolname}] failed while evaluating usage labels on '#{vm}' with an error: #{e}")
|
527
524
|
raise
|
@@ -536,21 +533,20 @@ module Vmpooler
|
|
536
533
|
next if value.nil?
|
537
534
|
return value if key == match
|
538
535
|
end
|
539
|
-
|
536
|
+
'none'
|
540
537
|
end
|
541
538
|
|
542
539
|
def purge_unused_vms_and_folders
|
543
540
|
global_purge = $config[:config]['purge_unconfigured_folders']
|
544
541
|
providers = $config[:providers].keys
|
545
|
-
providers.each do |
|
546
|
-
provider_purge = $config[:providers][
|
547
|
-
provider_purge = global_purge if provider_purge.nil?
|
542
|
+
providers.each do |provider_key|
|
543
|
+
provider_purge = $config[:providers][provider_key]['purge_unconfigured_folders'] || global_purge
|
548
544
|
if provider_purge
|
549
545
|
Thread.new do
|
550
546
|
begin
|
551
|
-
purge_vms_and_folders(
|
547
|
+
purge_vms_and_folders(provider_key)
|
552
548
|
rescue StandardError => e
|
553
|
-
$logger.log('s', "[!] failed while purging provider #{
|
549
|
+
$logger.log('s', "[!] failed while purging provider #{provider_key} VMs and folders with an error: #{e}")
|
554
550
|
end
|
555
551
|
end
|
556
552
|
end
|
@@ -559,14 +555,13 @@ module Vmpooler
|
|
559
555
|
end
|
560
556
|
|
561
557
|
# Return a list of pool folders
|
562
|
-
def pool_folders(
|
563
|
-
provider_name = provider.name
|
558
|
+
def pool_folders(provider_name)
|
564
559
|
folders = {}
|
565
560
|
$config[:pools].each do |pool|
|
566
|
-
next unless pool['provider'] == provider_name
|
561
|
+
next unless pool['provider'] == provider_name.to_s
|
567
562
|
|
568
563
|
folder_parts = pool['folder'].split('/')
|
569
|
-
datacenter =
|
564
|
+
datacenter = $providers[provider_name.to_s].get_target_datacenter_from_config(pool['name'])
|
570
565
|
folders[folder_parts.pop] = "#{datacenter}/vm/#{folder_parts.join('/')}"
|
571
566
|
end
|
572
567
|
folders
|
@@ -580,8 +575,9 @@ module Vmpooler
|
|
580
575
|
base.uniq
|
581
576
|
end
|
582
577
|
|
583
|
-
def purge_vms_and_folders(
|
584
|
-
|
578
|
+
def purge_vms_and_folders(provider_name)
|
579
|
+
provider = $providers[provider_name.to_s]
|
580
|
+
configured_folders = pool_folders(provider_name)
|
585
581
|
base_folders = get_base_folders(configured_folders)
|
586
582
|
whitelist = provider.provider_config['folder_whitelist']
|
587
583
|
provider.purge_unconfigured_folders(base_folders, configured_folders, whitelist)
|
@@ -1500,9 +1496,7 @@ module Vmpooler
|
|
1500
1496
|
def vms_ready?(request_id, redis)
|
1501
1497
|
catch :request_not_ready do
|
1502
1498
|
request_hash = redis.hgetall("vmpooler__odrequest__#{request_id}")
|
1503
|
-
|
1504
|
-
requested_platforms.each do |platform|
|
1505
|
-
platform_alias, pool, count = platform.split(':')
|
1499
|
+
Parsing.get_platform_pool_count(request_hash['requested']) do |platform_alias, pool, count|
|
1506
1500
|
pools_filled = redis.scard("vmpooler__#{request_id}__#{platform_alias}__#{pool}")
|
1507
1501
|
throw :request_not_ready unless pools_filled.to_i == count.to_i
|
1508
1502
|
end
|
@@ -1554,9 +1548,7 @@ module Vmpooler
|
|
1554
1548
|
|
1555
1549
|
def remove_vms_for_failed_request(request_id, expiration_ttl, redis)
|
1556
1550
|
request_hash = redis.hgetall("vmpooler__odrequest__#{request_id}")
|
1557
|
-
|
1558
|
-
requested_platforms.each do |platform|
|
1559
|
-
platform_alias, pool, _count = platform.split(':')
|
1551
|
+
Parsing.get_platform_pool_count(request_hash['requested']) do |platform_alias, pool, _count|
|
1560
1552
|
pools_filled = redis.smembers("vmpooler__#{request_id}__#{platform_alias}__#{pool}")
|
1561
1553
|
redis.pipelined do
|
1562
1554
|
pools_filled&.each do |vm|
|
@@ -29,7 +29,8 @@ module Vmpooler
|
|
29
29
|
logger.log('d', "[#{name}] ConnPool - Creating a connection pool of size #{connpool_size} with timeout #{connpool_timeout}")
|
30
30
|
@connection_pool = Vmpooler::PoolManager::GenericConnectionPool.new(
|
31
31
|
metrics: metrics,
|
32
|
-
|
32
|
+
connpool_type: 'provider_connection_pool',
|
33
|
+
connpool_provider: name,
|
33
34
|
size: connpool_size,
|
34
35
|
timeout: connpool_timeout
|
35
36
|
) do
|
@@ -25,7 +25,8 @@ module Vmpooler
|
|
25
25
|
logger.log('d', "[#{name}] ConnPool - Creating a connection pool of size #{connpool_size} with timeout #{connpool_timeout}")
|
26
26
|
@connection_pool = Vmpooler::PoolManager::GenericConnectionPool.new(
|
27
27
|
metrics: metrics,
|
28
|
-
|
28
|
+
connpool_type: 'provider_connection_pool',
|
29
|
+
connpool_provider: name,
|
29
30
|
size: connpool_size,
|
30
31
|
timeout: connpool_timeout
|
31
32
|
) do
|
@@ -298,7 +299,6 @@ module Vmpooler
|
|
298
299
|
template_path = pool['template']
|
299
300
|
target_folder_path = pool['folder']
|
300
301
|
target_datastore = pool['datastore']
|
301
|
-
target_cluster_name = get_target_cluster_from_config(pool_name)
|
302
302
|
target_datacenter_name = get_target_datacenter_from_config(pool_name)
|
303
303
|
|
304
304
|
# Get the template VM object
|
@@ -320,31 +320,19 @@ module Vmpooler
|
|
320
320
|
]
|
321
321
|
)
|
322
322
|
|
323
|
-
#
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
manage_host_selection = @config[:config]['manage_host_selection'] if @config[:config].key?('manage_host_selection')
|
330
|
-
if manage_host_selection
|
331
|
-
run_select_hosts(pool_name, @provider_hosts)
|
332
|
-
target_host = select_next_host(pool_name, @provider_hosts)
|
333
|
-
host_object = find_host_by_dnsname(connection, target_host)
|
334
|
-
relocate_spec.host = host_object
|
335
|
-
else
|
336
|
-
# Choose a cluster/host to place the new VM on
|
337
|
-
target_cluster_object = find_cluster(target_cluster_name, connection, target_datacenter_name)
|
338
|
-
relocate_spec.pool = target_cluster_object.resourcePool
|
323
|
+
# Check if alternate network configuration is specified and add configuration
|
324
|
+
if pool.key?('network')
|
325
|
+
template_vm_network_device = template_vm_object.config.hardware.device.grep(RbVmomi::VIM::VirtualEthernetCard).first
|
326
|
+
network_name = pool['network']
|
327
|
+
network_device = set_network_device(target_datacenter_name, template_vm_network_device, network_name, connection)
|
328
|
+
config_spec.deviceChange = [{ operation: 'edit', device: network_device }]
|
339
329
|
end
|
340
330
|
|
331
|
+
# Put the VM in the specified folder and resource pool
|
332
|
+
relocate_spec = create_relocate_spec(target_datastore, target_datacenter_name, pool_name, connection)
|
333
|
+
|
341
334
|
# Create a clone spec
|
342
|
-
clone_spec =
|
343
|
-
location: relocate_spec,
|
344
|
-
config: config_spec,
|
345
|
-
powerOn: true,
|
346
|
-
template: false
|
347
|
-
)
|
335
|
+
clone_spec = create_clone_spec(relocate_spec, config_spec)
|
348
336
|
|
349
337
|
begin
|
350
338
|
vm_target_folder = find_vm_folder(pool_name, connection)
|
@@ -356,7 +344,7 @@ module Vmpooler
|
|
356
344
|
raise
|
357
345
|
end
|
358
346
|
end
|
359
|
-
raise ArgumentError, "
|
347
|
+
raise ArgumentError, "Cannot find the configured folder for #{pool_name} #{target_folder_path}" unless vm_target_folder
|
360
348
|
|
361
349
|
# Create the new VM
|
362
350
|
new_vm_object = template_vm_object.CloneVM_Task(
|
@@ -370,6 +358,81 @@ module Vmpooler
|
|
370
358
|
vm_hash
|
371
359
|
end
|
372
360
|
|
361
|
+
def create_relocate_spec(target_datastore, target_datacenter_name, pool_name, connection)
|
362
|
+
pool = pool_config(pool_name)
|
363
|
+
target_cluster_name = get_target_cluster_from_config(pool_name)
|
364
|
+
|
365
|
+
relocate_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(
|
366
|
+
datastore: find_datastore(target_datastore, connection, target_datacenter_name),
|
367
|
+
diskMoveType: get_disk_backing(pool)
|
368
|
+
)
|
369
|
+
manage_host_selection = @config[:config]['manage_host_selection'] if @config[:config].key?('manage_host_selection')
|
370
|
+
if manage_host_selection
|
371
|
+
run_select_hosts(pool_name, @provider_hosts)
|
372
|
+
target_host = select_next_host(pool_name, @provider_hosts)
|
373
|
+
host_object = find_host_by_dnsname(connection, target_host)
|
374
|
+
relocate_spec.host = host_object
|
375
|
+
else
|
376
|
+
# Choose a cluster/host to place the new VM on
|
377
|
+
target_cluster_object = find_cluster(target_cluster_name, connection, target_datacenter_name)
|
378
|
+
relocate_spec.pool = target_cluster_object.resourcePool
|
379
|
+
end
|
380
|
+
relocate_spec
|
381
|
+
end
|
382
|
+
|
383
|
+
def create_clone_spec(relocate_spec, config_spec)
|
384
|
+
RbVmomi::VIM.VirtualMachineCloneSpec(
|
385
|
+
location: relocate_spec,
|
386
|
+
config: config_spec,
|
387
|
+
powerOn: true,
|
388
|
+
template: false
|
389
|
+
)
|
390
|
+
end
|
391
|
+
|
392
|
+
def set_network_device(datacenter_name, template_vm_network_device, network_name, connection)
|
393
|
+
# Retrieve network object
|
394
|
+
datacenter = connection.serviceInstance.find_datacenter(datacenter_name)
|
395
|
+
new_network = datacenter.network.find { |n| n.name == network_name }
|
396
|
+
|
397
|
+
raise("Cannot find network #{network_name} in datacenter #{datacenter_name}") unless new_network
|
398
|
+
|
399
|
+
# Determine network device type
|
400
|
+
# All possible device type options here: https://vdc-download.vmware.com/vmwb-repository/dcr-public/98d63b35-d822-47fe-a87a-ddefd469df06/2e3c7b58-f2bd-486e-8bb1-a75eb0640bee/doc/vim.vm.device.VirtualEthernetCard.html
|
401
|
+
network_device =
|
402
|
+
if template_vm_network_device.is_a? RbVmomi::VIM::VirtualVmxnet2
|
403
|
+
RbVmomi::VIM.VirtualVmxnet2
|
404
|
+
elsif template_vm_network_device.is_a? RbVmomi::VIM::VirtualVmxnet3
|
405
|
+
RbVmomi::VIM.VirtualVmxnet3
|
406
|
+
elsif template_vm_network_device.is_a? RbVmomi::VIM::VirtualE1000
|
407
|
+
RbVmomi::VIM.VirtualE1000
|
408
|
+
elsif template_vm_network_device.is_a? RbVmomi::VIM::VirtualE1000e
|
409
|
+
RbVmomi::VIM.VirtualE1000e
|
410
|
+
elsif template_vm_network_device.is_a? RbVmomi::VIM::VirtualSriovEthernetCard
|
411
|
+
RbVmomi::VIM.VirtualSriovEthernetCard
|
412
|
+
else
|
413
|
+
RbVmomi::VIM.VirtualPCNet32
|
414
|
+
end
|
415
|
+
|
416
|
+
# Set up new network device attributes
|
417
|
+
network_device.key = template_vm_network_device.key
|
418
|
+
network_device.deviceInfo = RbVmomi::VIM.Description(
|
419
|
+
label: template_vm_network_device.deviceInfo.label,
|
420
|
+
summary: network_name
|
421
|
+
)
|
422
|
+
network_device.backing = RbVmomi::VIM.VirtualEthernetCardNetworkBackingInfo(
|
423
|
+
deviceName: network_name,
|
424
|
+
network: new_network,
|
425
|
+
useAutoDetect: false
|
426
|
+
)
|
427
|
+
network_device.addressType = 'assigned'
|
428
|
+
network_device.connectable = RbVmomi::VIM.VirtualDeviceConnectInfo(
|
429
|
+
allowGuestControl: true,
|
430
|
+
startConnected: true,
|
431
|
+
connected: true
|
432
|
+
)
|
433
|
+
network_device
|
434
|
+
end
|
435
|
+
|
373
436
|
def create_disk(pool_name, vm_name, disk_size)
|
374
437
|
pool = pool_config(pool_name)
|
375
438
|
raise("Pool #{pool_name} does not exist for the provider #{name}") if pool.nil?
|