knife-vcenter 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/ISSUE_TEMPLATE.md +22 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +14 -0
- data/.gitignore +20 -0
- data/.rubocop.yml +18 -0
- data/.travis.yml +16 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +201 -0
- data/README.md +209 -0
- data/Rakefile +20 -0
- data/knife-vcenter.gemspec +38 -0
- data/lib/base.rb +35 -0
- data/lib/chef/knife/cloud/vcenter_service.rb +256 -0
- data/lib/chef/knife/cloud/vcenter_service_helpers.rb +55 -0
- data/lib/chef/knife/cloud/vcenter_service_options.rb +56 -0
- data/lib/chef/knife/vcenter_cluster_list.rb +58 -0
- data/lib/chef/knife/vcenter_datacenter_list.rb +51 -0
- data/lib/chef/knife/vcenter_host_list.rb +67 -0
- data/lib/chef/knife/vcenter_vm_clone.rb +100 -0
- data/lib/chef/knife/vcenter_vm_create.rb +82 -0
- data/lib/chef/knife/vcenter_vm_delete.rb +54 -0
- data/lib/chef/knife/vcenter_vm_list.rb +68 -0
- data/lib/chef/knife/vcenter_vm_show.rb +54 -0
- data/lib/knife-vcenter/version.rb +22 -0
- data/lib/lookup_service_helper.rb +463 -0
- data/lib/sso.rb +269 -0
- data/lib/support/clone_vm.rb +74 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/unit/vcenter_vm_list_spec.rb +67 -0
- metadata +257 -0
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
require 'rubocop/rake_task'
|
5
|
+
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
7
|
+
RuboCop::RakeTask.new(:style)
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'github_changelog_generator/task'
|
11
|
+
|
12
|
+
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
13
|
+
config.future_release = KnifeVcenter::VERSION
|
14
|
+
config.issues = true
|
15
|
+
end
|
16
|
+
rescue LoadError
|
17
|
+
puts 'github_changelog_generator is not available. gem install github_changelog_generator to generate changelogs'
|
18
|
+
end
|
19
|
+
|
20
|
+
task default: [ :spec, :style ]
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'knife-vcenter/version'
|
7
|
+
|
8
|
+
Gem::Specification.new do |spec|
|
9
|
+
spec.name = 'knife-vcenter'
|
10
|
+
spec.version = KnifeVcenter::VERSION
|
11
|
+
spec.authors = ['Chef Partner Engineering']
|
12
|
+
spec.email = ['partnereng@chef.io']
|
13
|
+
spec.summary = 'Knife plugin to VMware vCenter.'
|
14
|
+
spec.description = spec.summary
|
15
|
+
spec.homepage = 'https://github.com/chef/knife-vcenter'
|
16
|
+
spec.license = 'Apache 2.0'
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0")
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ['lib']
|
22
|
+
|
23
|
+
spec.add_dependency 'chef', '~> 12'
|
24
|
+
spec.add_dependency 'knife-cloud', '~> 1.2'
|
25
|
+
spec.add_dependency 'rb-readline', '~> 0.5'
|
26
|
+
spec.add_dependency 'rbvmomi', '~> 1.11'
|
27
|
+
spec.add_dependency 'savon', '~> 2.11'
|
28
|
+
spec.add_dependency 'vsphere-automation-sdk', '~> 2.5'
|
29
|
+
|
30
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
31
|
+
spec.add_development_dependency 'debase'
|
32
|
+
spec.add_development_dependency 'github_changelog_generator'
|
33
|
+
spec.add_development_dependency 'pry'
|
34
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
35
|
+
spec.add_development_dependency 'rubocop', '~> 0.35'
|
36
|
+
spec.add_development_dependency 'ruby-debug-ide', '~> 0.6.0'
|
37
|
+
|
38
|
+
end
|
data/lib/base.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Author:: Chef Partner Engineering (<partnereng@chef.io>)
|
4
|
+
# Copyright:: Copyright (c) 2017 Chef Software, Inc.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
require 'logger'
|
21
|
+
|
22
|
+
module Base
|
23
|
+
attr_accessor :log
|
24
|
+
|
25
|
+
def self.log
|
26
|
+
@log ||= init_logger
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.init_logger
|
30
|
+
log = Logger.new(STDOUT)
|
31
|
+
log.progname = 'Knife VCenter'
|
32
|
+
log.level = Logger::INFO
|
33
|
+
log
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,256 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Author:: Chef Partner Engineering (<partnereng@chef.io>)
|
4
|
+
# Copyright:: Copyright (c) 2017 Chef Software, Inc.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
require 'chef/knife/cloud/exceptions'
|
21
|
+
require 'chef/knife/cloud/service'
|
22
|
+
require 'chef/knife/cloud/helpers'
|
23
|
+
require 'chef/knife/cloud/vcenter_service_helpers'
|
24
|
+
require 'net/http'
|
25
|
+
require 'uri'
|
26
|
+
require 'json'
|
27
|
+
require 'ostruct'
|
28
|
+
require 'lookup_service_helper'
|
29
|
+
require 'vapi'
|
30
|
+
require 'com/vmware/cis'
|
31
|
+
require 'com/vmware/vcenter'
|
32
|
+
require 'com/vmware/vcenter/vm'
|
33
|
+
require 'sso'
|
34
|
+
require 'base'
|
35
|
+
require 'set'
|
36
|
+
require 'support/clone_vm'
|
37
|
+
|
38
|
+
class Chef
|
39
|
+
class Knife
|
40
|
+
class Cloud
|
41
|
+
class VcenterService < Service
|
42
|
+
include VcenterServiceHelpers
|
43
|
+
|
44
|
+
attr_reader :vapi_config, :session_svc, :session_id
|
45
|
+
attr_reader :connection_options, :ipaddress
|
46
|
+
|
47
|
+
def initialize(options={})
|
48
|
+
super(options)
|
49
|
+
|
50
|
+
# Using the information supplied, configure the connection to vCentre
|
51
|
+
lookup_service_helper = LookupServiceHelper.new(options[:host])
|
52
|
+
|
53
|
+
vapi_urls = lookup_service_helper.find_vapi_urls()
|
54
|
+
vapi_url = vapi_urls.values[0]
|
55
|
+
Base.log.info(format('Vapi URL: %s', vapi_url)) if options[:vcenter_logs]
|
56
|
+
|
57
|
+
# Create the VAPI config object
|
58
|
+
ssl_options = {}
|
59
|
+
ssl_options[:verify] = if options[:verify_ssl]
|
60
|
+
:peer
|
61
|
+
else
|
62
|
+
Base.log.warn('SSL Verification is turned OFF') if options[:vcenter_logs]
|
63
|
+
:none
|
64
|
+
end
|
65
|
+
@vapi_config = VAPI::Bindings::VapiConfig.new(vapi_url, ssl_options)
|
66
|
+
|
67
|
+
# get the SSO url
|
68
|
+
sso_url = lookup_service_helper.find_sso_url()
|
69
|
+
sso = SSO::Connection.new(sso_url).login(options[:username], options[:password])
|
70
|
+
token = sso.request_bearer_token()
|
71
|
+
vapi_config.set_security_context(
|
72
|
+
VAPI::Security.create_saml_bearer_security_context(token.to_s)
|
73
|
+
)
|
74
|
+
|
75
|
+
# Login and get the session information
|
76
|
+
@session_svc = Com::Vmware::Cis::Session.new(vapi_config)
|
77
|
+
@session_id = session_svc.create()
|
78
|
+
vapi_config.set_security_context(
|
79
|
+
VAPI::Security.create_session_security_context(session_id)
|
80
|
+
)
|
81
|
+
|
82
|
+
# Set the class properties for the rbvmomi connections
|
83
|
+
@connection_options = {
|
84
|
+
user: options[:username],
|
85
|
+
password: options[:password],
|
86
|
+
insecure: options[:verify_ssl] ? false : true,
|
87
|
+
host: options[:host],
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
def create_server(options={})
|
92
|
+
|
93
|
+
# Create the vm object
|
94
|
+
vmobj = Com::Vmware::Vcenter::VM.new(vapi_config)
|
95
|
+
|
96
|
+
# Use the option to determine now a new machine is being created
|
97
|
+
case options[:type]
|
98
|
+
when "clone"
|
99
|
+
|
100
|
+
# Some of ht eoptions need to be the ID of the component in VMWAre
|
101
|
+
# Update these using the REST API so that they can be passed to the support library
|
102
|
+
options[:targethost] = get_host(options[:targethost])
|
103
|
+
|
104
|
+
# Configure the folder option as a has with the name an the id
|
105
|
+
options[:folder] = {
|
106
|
+
name: options[:folder],
|
107
|
+
id: get_folder(options[:folder])
|
108
|
+
} unless options[:folder].nil?
|
109
|
+
|
110
|
+
# Clone the machine using the support library
|
111
|
+
clone_obj = Support::CloneVm.new(connection_options, options)
|
112
|
+
@ipaddress = clone_obj.clone()
|
113
|
+
|
114
|
+
# return an object from the restapi
|
115
|
+
return get_server(options[:name])
|
116
|
+
|
117
|
+
when "create"
|
118
|
+
|
119
|
+
# Create the placement object
|
120
|
+
placementspec = Com::Vmware::Vcenter::VM::PlacementSpec.new()
|
121
|
+
placementspec.folder = get_folder(options[:folder])
|
122
|
+
placementspec.host = get_host(options[:targethost])
|
123
|
+
placementspec.datastore = get_datastore(options[:datastore])
|
124
|
+
placementspec.resource_pool = get_resourcepool(options[:resource_pool])
|
125
|
+
|
126
|
+
# Create the CreateSpec object
|
127
|
+
createspec = Com::Vmware::Vcenter::VM::CreateSpec.new()
|
128
|
+
|
129
|
+
createspec.name = options[:name]#
|
130
|
+
puts "seting the OS"
|
131
|
+
createspec.guest_OS = Com::Vmware::Vcenter::Vm::GuestOS::UBUNTU_64
|
132
|
+
puts "setting the placement"
|
133
|
+
createspec.placement = placementspec
|
134
|
+
|
135
|
+
# Create the new machine
|
136
|
+
begin
|
137
|
+
vm = vmobj.create(createspec)
|
138
|
+
rescue => e
|
139
|
+
puts e.message
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def list_servers
|
145
|
+
# get a list of vms from the API
|
146
|
+
Com::Vmware::Vcenter::VM.new(vapi_config).list()
|
147
|
+
end
|
148
|
+
|
149
|
+
def list_hosts
|
150
|
+
# return a list of the hosts in the vcenter
|
151
|
+
Com::Vmware::Vcenter::Host.new(vapi_config).list()
|
152
|
+
end
|
153
|
+
|
154
|
+
def list_datacenters
|
155
|
+
Com::Vmware::Vcenter::Datacenter.new(vapi_config).list()
|
156
|
+
end
|
157
|
+
|
158
|
+
def list_clusters
|
159
|
+
Com::Vmware::Vcenter::Cluster.new(vapi_config).list()
|
160
|
+
end
|
161
|
+
|
162
|
+
def get_folder(name)
|
163
|
+
# Create a filter to ensure that only the named folder is returned
|
164
|
+
filter = Com::Vmware::Vcenter::Folder::FilterSpec.new({names: Set.new([name])})
|
165
|
+
# filter.names = name
|
166
|
+
folder_obj = Com::Vmware::Vcenter::Folder.new(vapi_config)
|
167
|
+
folder = folder_obj.list(filter)
|
168
|
+
|
169
|
+
folder[0].folder
|
170
|
+
end
|
171
|
+
|
172
|
+
def get_host(name)
|
173
|
+
filter = Com::Vmware::Vcenter::Host::FilterSpec.new({names: Set.new([name])})
|
174
|
+
host_obj = Com::Vmware::Vcenter::Host.new(vapi_config)
|
175
|
+
host = host_obj.list(filter)
|
176
|
+
host[0].host
|
177
|
+
end
|
178
|
+
|
179
|
+
def get_datastore(name)
|
180
|
+
filter = Com::Vmware::Vcenter::Datastore::FilterSpec.new({names: Set.new([name])})
|
181
|
+
datastore_obj = Com::Vmware::Vcenter::Datastore.new(vapi_config)
|
182
|
+
datastore = datastore_obj.list(filter)
|
183
|
+
datastore[0].datastore
|
184
|
+
end
|
185
|
+
|
186
|
+
def get_resourcepool(name)
|
187
|
+
filter = Com::Vmware::Vcenter::ResourcePool::FilterSpec.new({names: Set.new([name])})
|
188
|
+
resource_pool_obj = Com::Vmware::Vcenter::ResourcePool.new(vapi_config)
|
189
|
+
resource_pool = resource_pool_obj.list(filter)
|
190
|
+
resource_pool[0].resource_pool
|
191
|
+
end
|
192
|
+
|
193
|
+
def get_server(name)
|
194
|
+
filter = Com::Vmware::Vcenter::VM::FilterSpec.new({names: Set.new([name])})
|
195
|
+
vm_obj = Com::Vmware::Vcenter::VM.new(vapi_config)
|
196
|
+
vm_obj.list(filter)[0]
|
197
|
+
end
|
198
|
+
|
199
|
+
def delete_vm(name)
|
200
|
+
vm = get_server(name)
|
201
|
+
server_summary(vm)
|
202
|
+
ui.msg('')
|
203
|
+
|
204
|
+
ui.confirm('Do you really want to be delete this virtual machine')
|
205
|
+
|
206
|
+
vm_obj = Com::Vmware::Vcenter::VM.new(vapi_config)
|
207
|
+
|
208
|
+
# check the power state of the machine, if it is powered on turn it off
|
209
|
+
if vm.power_state.value == "POWERED_ON"
|
210
|
+
power = Com::Vmware::Vcenter::Vm::Power.new(vapi_config)
|
211
|
+
ui.msg('Shutting down machine')
|
212
|
+
power.stop(vm.vm)
|
213
|
+
end
|
214
|
+
|
215
|
+
vm_obj.delete(vm.vm)
|
216
|
+
end
|
217
|
+
|
218
|
+
def server_summary(server, _coloumns_with_inf=nil)
|
219
|
+
msg_pair('ID', server.vm)
|
220
|
+
msg_pair('Name', server.name)
|
221
|
+
msg_pair('Power State', server.power_state)
|
222
|
+
end
|
223
|
+
|
224
|
+
=begin
|
225
|
+
def bootstrap_common_params(bootstrap)
|
226
|
+
bootstrap.config[:run_list] = config[:run_list]
|
227
|
+
bootstrap.config[:environment] = get_config(:environment)
|
228
|
+
bootstrap.config[:first_boot_attributes] = get_config(:first_boot_attributes)
|
229
|
+
bootstrap.config[:chef_node_name] = get_config(:chef_node_name)
|
230
|
+
bootstrap.config[:node_ssl_verify_mode] = get_config(:node_ssl_verify_mode)
|
231
|
+
bootstrap
|
232
|
+
end
|
233
|
+
|
234
|
+
def bootstrap_for_node
|
235
|
+
Chef::Knife::Bootstrap.load_deps
|
236
|
+
bootstrap = Chef::Knife::Bootstrap.new
|
237
|
+
bootstrap.name_args = [config[:fqdn]]
|
238
|
+
bootstrap.config[:ssh_user] = get_config(:ssh_user)
|
239
|
+
bootstrap.config[:ssh_password] = get_config(:ssh_password)
|
240
|
+
bootstrap.config[:ssh_port] = get_config(:ssh_port)
|
241
|
+
bootstrap.config[:identity_file] = get_config(:identity_file)
|
242
|
+
bootstrap.config[:use_sudo] = true unless get_config(:ssh_user) == 'root'
|
243
|
+
bootstrap.config[:use_sudo_password] = true unless get_config(:ssh_user) == 'root'
|
244
|
+
bootstrap.config[:log_level] = get_config(:log_level)
|
245
|
+
bootstrap_common_params(bootstrap)
|
246
|
+
end
|
247
|
+
=end
|
248
|
+
private
|
249
|
+
|
250
|
+
def cleanup
|
251
|
+
session_svc.delete() unless session_id.nil?
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Author:: Chef Partner Engineering (<partnereng@chef.io>)
|
4
|
+
# Copyright:: Copyright (c) 2017 Chef Software, Inc.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
require 'chef/knife/cloud/helpers'
|
21
|
+
|
22
|
+
class Chef
|
23
|
+
class Knife
|
24
|
+
class Cloud
|
25
|
+
module VcenterServiceHelpers
|
26
|
+
include Chef::Knife::Cloud::Helpers
|
27
|
+
|
28
|
+
def create_service_instance
|
29
|
+
Chef::Knife::Cloud::VcenterService.new(username: locate_config_value(:vcenter_username),
|
30
|
+
password: locate_config_value(:vcenter_password),
|
31
|
+
host: locate_config_value(:vcenter_host),
|
32
|
+
verify_ssl: verify_ssl?)
|
33
|
+
end
|
34
|
+
|
35
|
+
def verify_ssl?
|
36
|
+
!locate_config_value(:vcenter_disable_ssl_verify)
|
37
|
+
end
|
38
|
+
|
39
|
+
def validate!
|
40
|
+
check_for_missing_config_values!(:vcenter_username, :vcenter_password, :vcenter_host)
|
41
|
+
end
|
42
|
+
|
43
|
+
# rubocop:disable Style/GuardClause
|
44
|
+
def check_for_missing_config_values!(*keys)
|
45
|
+
missing = keys.select { |x| locate_config_value(x).nil? }
|
46
|
+
|
47
|
+
unless missing.empty?
|
48
|
+
ui.error(format("The following required parameters are missing: %s", missing.join(', ')))
|
49
|
+
exit(1)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Author:: Chef Partner Engineering (<partnereng@chef.io>)
|
4
|
+
# Copyright:: Copyright (c) 2017 Chef Software, Inc.
|
5
|
+
# License:: Apache License, Version 2.0
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
|
20
|
+
class Chef
|
21
|
+
class Knife
|
22
|
+
class Cloud
|
23
|
+
# rubocop:disable Style/AlignParameters
|
24
|
+
# runodop:disable Metrics/BlockLength
|
25
|
+
module VcenterServiceOptions
|
26
|
+
def self.included(includer)
|
27
|
+
includer.class_eval do
|
28
|
+
option :vcenter_username,
|
29
|
+
long: '--vcenter-username USERNAME',
|
30
|
+
description: 'Username to use to connect to the VCenter API'
|
31
|
+
|
32
|
+
option :vcenter_password,
|
33
|
+
long: '--vcenter-password PASSWORD',
|
34
|
+
description: 'Password associated with the specified user'
|
35
|
+
|
36
|
+
option :vcenter_host,
|
37
|
+
long: '--vcenter-host HOST',
|
38
|
+
description: 'Host to target for operations'
|
39
|
+
|
40
|
+
option :vcenter_disable_ssl_verify,
|
41
|
+
long: '--vcenter-disable-ssl-verify',
|
42
|
+
description: 'Skip any SSL verification for the API',
|
43
|
+
boolean: true,
|
44
|
+
default: false
|
45
|
+
|
46
|
+
option :vcenter_logs,
|
47
|
+
long: '--vcenter-logs',
|
48
|
+
description: 'Whether or not to display logs from VCenter SDK. Default: false',
|
49
|
+
boolean: true,
|
50
|
+
default: false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|