knife-vsphere 0.9.0 → 0.9.5

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.
@@ -1,45 +1,45 @@
1
- #
2
- # Author:: Jesse Campbell (<hikeit@gmail.com>)
3
- # License:: Apache License, Version 2.0
4
- #
5
- require 'chef/knife'
6
- require 'chef/knife/BaseVsphereCommand'
7
-
8
- # Lists all known pools in the configured datacenter
9
- class Chef::Knife::VspherePoolList < Chef::Knife::BaseVsphereCommand
10
-
11
- banner "knife vsphere pool list"
12
-
13
- get_common_options
14
-
15
- def traverse_folders(folder)
16
- puts "#{ui.color("#{folder.class}", :cyan)}: "+(folder.path[3..-1].map{|x| x[1]}.*'/')
17
- folders = find_all_in_folder(folder, RbVmomi::VIM::ManagedObject)
18
- unless folders.nil?
19
- folders.each do |child|
20
- traverse_folders(child)
21
- end
22
- end
23
- end
24
-
25
- def find_pool_folder(folderName)
26
- dcname = get_config(:vsphere_dc)
27
- dc = config[:vim].serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
28
- baseEntity = dc.hostFolder
29
- entityArray = folderName.split('/')
30
- entityArray.each do |entityArrItem|
31
- if entityArrItem != ''
32
- baseEntity = baseEntity.childEntity.grep(RbVmomi::VIM::ManagedObject).find { |f| f.name == entityArrItem } or
33
- abort "no such folder #{folderName} while looking for #{entityArrItem}"
34
- end
35
- end
36
- baseEntity
37
- end
38
-
39
- def run
40
- $stdout.sync = true
41
- vim = get_vim_connection
42
- baseFolder = find_pool_folder(get_config(:folder));
43
- traverse_folders(baseFolder)
44
- end
45
- end
1
+ #
2
+ # Author:: Jesse Campbell (<hikeit@gmail.com>)
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ require 'chef/knife'
6
+ require 'chef/knife/base_vsphere_command'
7
+
8
+ # Lists all known pools in the configured datacenter
9
+ class Chef::Knife::VspherePoolList < Chef::Knife::BaseVsphereCommand
10
+
11
+ banner "knife vsphere pool list"
12
+
13
+ get_common_options
14
+
15
+ def traverse_folders(folder)
16
+ puts "#{ui.color("#{folder.class}", :cyan)}: "+(folder.path[3..-1].map { |x| x[1] }.* '/')
17
+ folders = find_all_in_folder(folder, RbVmomi::VIM::ManagedObject)
18
+ unless folders.nil?
19
+ folders.each do |child|
20
+ traverse_folders(child)
21
+ end
22
+ end
23
+ end
24
+
25
+ def find_pool_folder(folderName)
26
+ dcname = get_config(:vsphere_dc)
27
+ dc = config[:vim].serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
28
+ baseEntity = dc.hostFolder
29
+ entityArray = folderName.split('/')
30
+ entityArray.each do |entityArrItem|
31
+ if entityArrItem != ''
32
+ baseEntity = baseEntity.childEntity.grep(RbVmomi::VIM::ManagedObject).find { |f| f.name == entityArrItem } or
33
+ abort "no such folder #{folderName} while looking for #{entityArrItem}"
34
+ end
35
+ end
36
+ baseEntity
37
+ end
38
+
39
+ def run
40
+ $stdout.sync = true
41
+ vim = get_vim_connection
42
+ baseFolder = find_pool_folder(get_config(:folder));
43
+ traverse_folders(baseFolder)
44
+ end
45
+ end
@@ -1,32 +1,32 @@
1
- #
2
- # Author:: Ezra Pagel (<ezra@cpan.org>)
3
- # License:: Apache License, Version 2.0
4
- #
5
-
6
- require 'chef/knife'
7
- require 'chef/knife/BaseVsphereCommand'
8
-
9
- # Lists all known VM templates in the configured datacenter
10
- class Chef::Knife::VsphereTemplateList < Chef::Knife::BaseVsphereCommand
11
-
12
- banner "knife vsphere template list"
13
-
14
- get_common_options
15
-
16
- def run
17
-
18
- $stdout.sync = true
19
- $stderr.sync = true
20
-
21
- vim = get_vim_connection
22
-
23
- baseFolder = find_folder(get_config(:folder));
24
-
25
- vms = find_all_in_folder(baseFolder, RbVmomi::VIM::VirtualMachine).
26
- select {|v| !v.config.nil? && v.config.template == true }
27
-
28
- vms.each do |vm|
29
- puts "#{ui.color("Template Name", :cyan)}: #{vm.name}"
30
- end
31
- end
32
- end
1
+ #
2
+ # Author:: Ezra Pagel (<ezra@cpan.org>)
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+
6
+ require 'chef/knife'
7
+ require 'chef/knife/base_vsphere_command'
8
+
9
+ # Lists all known VM templates in the configured datacenter
10
+ class Chef::Knife::VsphereTemplateList < Chef::Knife::BaseVsphereCommand
11
+
12
+ banner "knife vsphere template list"
13
+
14
+ get_common_options
15
+
16
+ def run
17
+
18
+ $stdout.sync = true
19
+ $stderr.sync = true
20
+
21
+ vim = get_vim_connection
22
+
23
+ baseFolder = find_folder(get_config(:folder));
24
+
25
+ vms = find_all_in_folder(baseFolder, RbVmomi::VIM::VirtualMachine).
26
+ select { |v| !v.config.nil? && v.config.template == true }
27
+
28
+ vms.each do |vm|
29
+ puts "#{ui.color("Template Name", :cyan)}: #{vm.name}"
30
+ end
31
+ end
32
+ end
@@ -1,37 +1,38 @@
1
- # Author: Jesse Campbell
2
- #
3
- # Permission to use, copy, modify, and/or distribute this software for
4
- # any purpose with or without fee is hereby granted, provided that the
5
- # above copyright notice and this permission notice appear in all
6
- # copies.
7
- #
8
- # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
9
- # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
10
- # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
11
- # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12
- # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
13
- # OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
14
- # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
- # PERFORMANCE OF THIS SOFTWARE
16
-
17
- require 'chef/knife'
18
- require 'chef/knife/BaseVsphereCommand'
19
-
20
- # Lists all known data stores in datacenter with sizes
21
- class Chef::Knife::VsphereVlanList < Chef::Knife::BaseVsphereCommand
22
-
23
- banner "knife vsphere vlan list"
24
-
25
- get_common_options
26
- def run
27
- $stdout.sync = true
28
-
29
- vim = get_vim_connection
30
- dcname = get_config(:vsphere_dc)
31
- dc = config[:vim].serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
32
- dc.network.each do |network|
33
- puts "#{ui.color("VLAN", :cyan)}: #{network.name}"
34
- end
35
- end
36
- end
37
-
1
+ # Author: Jesse Campbell
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for
4
+ # any purpose with or without fee is hereby granted, provided that the
5
+ # above copyright notice and this permission notice appear in all
6
+ # copies.
7
+ #
8
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
9
+ # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
10
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
11
+ # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12
+ # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
13
+ # OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
14
+ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ # PERFORMANCE OF THIS SOFTWARE
16
+
17
+ require 'chef/knife'
18
+ require 'chef/knife/base_vsphere_command'
19
+
20
+ # Lists all known data stores in datacenter with sizes
21
+ class Chef::Knife::VsphereVlanList < Chef::Knife::BaseVsphereCommand
22
+
23
+ banner "knife vsphere vlan list"
24
+
25
+ get_common_options
26
+
27
+ def run
28
+ $stdout.sync = true
29
+
30
+ vim = get_vim_connection
31
+ dcname = get_config(:vsphere_dc)
32
+ dc = config[:vim].serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
33
+ dc.network.each do |network|
34
+ puts "#{ui.color("VLAN", :cyan)}: #{network.name}"
35
+ end
36
+ end
37
+ end
38
+
@@ -7,7 +7,7 @@
7
7
  #
8
8
 
9
9
  require 'chef/knife'
10
- require 'chef/knife/BaseVsphereCommand'
10
+ require 'chef/knife/base_vsphere_command'
11
11
  require 'rbvmomi'
12
12
  require 'netaddr'
13
13
 
@@ -18,244 +18,244 @@ require 'netaddr'
18
18
  # --chostname NODENAME --cdomain NODEDOMAIN
19
19
  class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
20
20
 
21
- banner "knife vsphere vm clone VMNAME (options)"
21
+ banner "knife vsphere vm clone VMNAME (options)"
22
22
 
23
- get_common_options
23
+ get_common_options
24
24
 
25
- option :dest_folder,
26
- :long => "--dest-folder FOLDER",
27
- :description => "The folder into which to put the cloned VM"
25
+ option :dest_folder,
26
+ :long => "--dest-folder FOLDER",
27
+ :description => "The folder into which to put the cloned VM"
28
28
 
29
- option :datastore,
30
- :long => "--datastore STORE",
31
- :description => "The datastore into which to put the cloned VM"
32
-
33
- option :resource_pool,
34
- :long => "--resource-pool POOL",
35
- :description => "The resource pool into which to put the cloned VM"
36
-
37
- option :source_vm,
38
- :long => "--template TEMPLATE",
39
- :description => "The source VM / Template to clone from",
40
- :required => true
41
-
42
- option :annotation,
43
- :long => "--annotation TEXT",
44
- :description => "Add TEXT in Notes field from annotation"
45
-
46
- option :customization_spec,
47
- :long => "--cspec CUST_SPEC",
48
- :description => "The name of any customization specification to apply"
49
-
50
- option :customization_plugin,
51
- :long => "--cplugin CUST_PLUGIN_PATH",
52
- :description => "Path to plugin that implements KnifeVspherePlugin.customize_clone_spec and/or KnifeVspherePlugin.reconfig_vm"
53
-
54
- option :customization_plugin_data,
55
- :long => "--cplugin-data CUST_PLUGIN_DATA",
56
- :description => "String of data to pass to the plugin. Use any format you wish."
57
-
58
- option :customization_vlan,
59
- :long => "--cvlan CUST_VLAN",
60
- :description => "VLAN name for network adapter to join"
61
-
62
- option :customization_ips,
63
- :long => "--cips CUST_IPS",
64
- :description => "Comma-delimited list of CIDR IPs for customization"
65
-
66
- option :customization_dns_ips,
67
- :long => "--cdnsips CUST_DNS_IPS",
68
- :description => "Comma-delimited list of DNS IP addresses"
69
-
70
- option :customization_dns_suffixes,
71
- :long => "--cdnssuffix CUST_DNS_SUFFIXES",
72
- :description => "Comma-delimited list of DNS search suffixes"
73
-
74
- option :customization_gw,
75
- :long => "--cgw CUST_GW",
76
- :description => "CIDR IP of gateway for customization"
77
-
78
- option :customization_hostname,
79
- :long => "--chostname CUST_HOSTNAME",
80
- :description => "Unqualified hostname for customization"
81
-
82
- option :customization_domain,
83
- :long => "--cdomain CUST_DOMAIN",
84
- :description => "Domain name for customization"
85
-
86
- option :customization_tz,
87
- :long => "--ctz CUST_TIMEZONE",
88
- :description => "Timezone invalid 'Area/Location' format"
89
-
90
- option :customization_cpucount,
91
- :long => "--ccpu CUST_CPU_COUNT",
92
- :description => "Number of CPUs"
93
-
94
- option :customization_memory,
95
- :long => "--cram CUST_MEMORY_GB",
96
- :description => "Gigabytes of RAM"
97
-
98
- option :power,
99
- :long => "--start",
100
- :description => "Indicates whether to start the VM after a successful clone",
101
- :boolean => false
102
-
103
- option :bootstrap,
104
- :long => "--bootstrap",
105
- :description => "Indicates whether to bootstrap the VM",
106
- :boolean => false
107
-
108
- option :fqdn,
109
- :long => "--fqdn SERVER_FQDN",
110
- :description => "Fully qualified hostname for bootstrapping"
111
-
112
- option :ssh_user,
113
- :short => "-x USERNAME",
114
- :long => "--ssh-user USERNAME",
115
- :description => "The ssh username"
116
- $default[:ssh_user] = "root"
117
-
118
- option :ssh_password,
119
- :short => "-P PASSWORD",
120
- :long => "--ssh-password PASSWORD",
121
- :description => "The ssh password"
122
-
123
- option :ssh_port,
124
- :short => "-p PORT",
125
- :long => "--ssh-port PORT",
126
- :description => "The ssh port"
127
- $default[:ssh_port] = 22
128
-
129
- option :identity_file,
130
- :short => "-i IDENTITY_FILE",
131
- :long => "--identity-file IDENTITY_FILE",
132
- :description => "The SSH identity file used for authentication"
133
-
134
- option :chef_node_name,
135
- :short => "-N NAME",
136
- :long => "--node-name NAME",
137
- :description => "The Chef node name for your new node"
138
-
139
- option :prerelease,
140
- :long => "--prerelease",
141
- :description => "Install the pre-release chef gems",
142
- :boolean => false
143
-
144
- option :bootstrap_version,
145
- :long => "--bootstrap-version VERSION",
146
- :description => "The version of Chef to install",
147
- :proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
148
-
149
- option :bootstrap_proxy,
150
- :long => "--bootstrap-proxy PROXY_URL",
151
- :description => "The proxy server for the node being bootstrapped",
152
- :proc => Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
153
-
154
- option :distro,
155
- :short => "-d DISTRO",
156
- :long => "--distro DISTRO",
157
- :description => "Bootstrap a distro using a template"
158
-
159
- option :template_file,
160
- :long => "--template-file TEMPLATE",
161
- :description => "Full path to location of template to use"
29
+ option :datastore,
30
+ :long => "--datastore STORE",
31
+ :description => "The datastore into which to put the cloned VM"
32
+
33
+ option :resource_pool,
34
+ :long => "--resource-pool POOL",
35
+ :description => "The resource pool into which to put the cloned VM"
36
+
37
+ option :source_vm,
38
+ :long => "--template TEMPLATE",
39
+ :description => "The source VM / Template to clone from",
40
+ :required => true
41
+
42
+ option :annotation,
43
+ :long => "--annotation TEXT",
44
+ :description => "Add TEXT in Notes field from annotation"
45
+
46
+ option :customization_spec,
47
+ :long => "--cspec CUST_SPEC",
48
+ :description => "The name of any customization specification to apply"
49
+
50
+ option :customization_plugin,
51
+ :long => "--cplugin CUST_PLUGIN_PATH",
52
+ :description => "Path to plugin that implements KnifeVspherePlugin.customize_clone_spec and/or KnifeVspherePlugin.reconfig_vm"
53
+
54
+ option :customization_plugin_data,
55
+ :long => "--cplugin-data CUST_PLUGIN_DATA",
56
+ :description => "String of data to pass to the plugin. Use any format you wish."
57
+
58
+ option :customization_vlan,
59
+ :long => "--cvlan CUST_VLAN",
60
+ :description => "VLAN name for network adapter to join"
61
+
62
+ option :customization_ips,
63
+ :long => "--cips CUST_IPS",
64
+ :description => "Comma-delimited list of CIDR IPs for customization"
65
+
66
+ option :customization_dns_ips,
67
+ :long => "--cdnsips CUST_DNS_IPS",
68
+ :description => "Comma-delimited list of DNS IP addresses"
69
+
70
+ option :customization_dns_suffixes,
71
+ :long => "--cdnssuffix CUST_DNS_SUFFIXES",
72
+ :description => "Comma-delimited list of DNS search suffixes"
73
+
74
+ option :customization_gw,
75
+ :long => "--cgw CUST_GW",
76
+ :description => "CIDR IP of gateway for customization"
77
+
78
+ option :customization_hostname,
79
+ :long => "--chostname CUST_HOSTNAME",
80
+ :description => "Unqualified hostname for customization"
81
+
82
+ option :customization_domain,
83
+ :long => "--cdomain CUST_DOMAIN",
84
+ :description => "Domain name for customization"
85
+
86
+ option :customization_tz,
87
+ :long => "--ctz CUST_TIMEZONE",
88
+ :description => "Timezone invalid 'Area/Location' format"
89
+
90
+ option :customization_cpucount,
91
+ :long => "--ccpu CUST_CPU_COUNT",
92
+ :description => "Number of CPUs"
93
+
94
+ option :customization_memory,
95
+ :long => "--cram CUST_MEMORY_GB",
96
+ :description => "Gigabytes of RAM"
97
+
98
+ option :power,
99
+ :long => "--start",
100
+ :description => "Indicates whether to start the VM after a successful clone",
101
+ :boolean => false
102
+
103
+ option :bootstrap,
104
+ :long => "--bootstrap",
105
+ :description => "Indicates whether to bootstrap the VM",
106
+ :boolean => false
107
+
108
+ option :fqdn,
109
+ :long => "--fqdn SERVER_FQDN",
110
+ :description => "Fully qualified hostname for bootstrapping"
111
+
112
+ option :ssh_user,
113
+ :short => "-x USERNAME",
114
+ :long => "--ssh-user USERNAME",
115
+ :description => "The ssh username"
116
+ $default[:ssh_user] = "root"
117
+
118
+ option :ssh_password,
119
+ :short => "-P PASSWORD",
120
+ :long => "--ssh-password PASSWORD",
121
+ :description => "The ssh password"
122
+
123
+ option :ssh_port,
124
+ :short => "-p PORT",
125
+ :long => "--ssh-port PORT",
126
+ :description => "The ssh port"
127
+ $default[:ssh_port] = 22
128
+
129
+ option :identity_file,
130
+ :short => "-i IDENTITY_FILE",
131
+ :long => "--identity-file IDENTITY_FILE",
132
+ :description => "The SSH identity file used for authentication"
133
+
134
+ option :chef_node_name,
135
+ :short => "-N NAME",
136
+ :long => "--node-name NAME",
137
+ :description => "The Chef node name for your new node"
138
+
139
+ option :prerelease,
140
+ :long => "--prerelease",
141
+ :description => "Install the pre-release chef gems",
142
+ :boolean => false
143
+
144
+ option :bootstrap_version,
145
+ :long => "--bootstrap-version VERSION",
146
+ :description => "The version of Chef to install",
147
+ :proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
148
+
149
+ option :bootstrap_proxy,
150
+ :long => "--bootstrap-proxy PROXY_URL",
151
+ :description => "The proxy server for the node being bootstrapped",
152
+ :proc => Proc.new { |p| Chef::Config[:knife][:bootstrap_proxy] = p }
153
+
154
+ option :distro,
155
+ :short => "-d DISTRO",
156
+ :long => "--distro DISTRO",
157
+ :description => "Bootstrap a distro using a template"
158
+
159
+ option :template_file,
160
+ :long => "--template-file TEMPLATE",
161
+ :description => "Full path to location of template to use"
162
162
 
163
163
  option :run_list,
164
- :short => "-r RUN_LIST",
165
- :long => "--run-list RUN_LIST",
166
- :description => "Comma separated list of roles/recipes to apply"
164
+ :short => "-r RUN_LIST",
165
+ :long => "--run-list RUN_LIST",
166
+ :description => "Comma separated list of roles/recipes to apply"
167
167
  $default[:run_list] = ''
168
168
 
169
169
  option :secret_file,
170
- :long => "--secret-file SECRET_FILE",
171
- :description => "A file containing the secret key to use to encrypt data bag item values"
170
+ :long => "--secret-file SECRET_FILE",
171
+ :description => "A file containing the secret key to use to encrypt data bag item values"
172
172
  $default[:secret_file] = ''
173
173
 
174
- option :no_host_key_verify,
175
- :long => "--no-host-key-verify",
176
- :description => "Disable host key verification",
177
- :boolean => true
174
+ option :no_host_key_verify,
175
+ :long => "--no-host-key-verify",
176
+ :description => "Disable host key verification",
177
+ :boolean => true
178
178
 
179
179
  option :first_boot_attributes,
180
- :short => "-j JSON_ATTRIBS",
181
- :long => "--json-attributes",
182
- :description => "A JSON string to be added to the first run of chef-client",
183
- :proc => lambda { |o| JSON.parse(o) },
184
- :default => {}
185
-
186
- option :disable_customization,
187
- :long => "--disable-customization",
188
- :description => "Disable default customization",
189
- :boolean => true,
190
- :default => false
180
+ :short => "-j JSON_ATTRIBS",
181
+ :long => "--json-attributes",
182
+ :description => "A JSON string to be added to the first run of chef-client",
183
+ :proc => lambda { |o| JSON.parse(o) },
184
+ :default => {}
185
+
186
+ option :disable_customization,
187
+ :long => "--disable-customization",
188
+ :description => "Disable default customization",
189
+ :boolean => true,
190
+ :default => false
191
191
 
192
192
  option :log_level,
193
- :short => "-l LEVEL",
194
- :long => "--log_level",
195
- :description => "Set the log level (debug, info, warn, error, fatal) for chef-client",
196
- :proc => lambda { |l| l.to_sym }
197
-
198
- def run
199
- $stdout.sync = true
200
-
201
- vmname = @name_args[0]
202
- if vmname.nil?
203
- show_usage
204
- fatal_exit("You must specify a virtual machine name")
205
- end
206
- config[:chef_node_name] = vmname unless config[:chef_node_name]
207
- config[:vmname] = vmname
193
+ :short => "-l LEVEL",
194
+ :long => "--log_level",
195
+ :description => "Set the log level (debug, info, warn, error, fatal) for chef-client",
196
+ :proc => lambda { |l| l.to_sym }
197
+
198
+ def run
199
+ $stdout.sync = true
200
+
201
+ vmname = @name_args[0]
202
+ if vmname.nil?
203
+ show_usage
204
+ fatal_exit("You must specify a virtual machine name")
205
+ end
206
+ config[:chef_node_name] = vmname unless config[:chef_node_name]
207
+ config[:vmname] = vmname
208
208
 
209
- if get_config(:bootstrap) && get_config(:distro) && !@@chef_config_dir
210
- fatal_exit("Can't find .chef for bootstrap files. chdir to a location with a .chef directory and try again")
211
- end
209
+ if get_config(:bootstrap) && get_config(:distro) && !@@chef_config_dir
210
+ fatal_exit("Can't find .chef for bootstrap files. chdir to a location with a .chef directory and try again")
211
+ end
212
212
 
213
- vim = get_vim_connection
213
+ vim = get_vim_connection
214
214
 
215
215
  dcname = get_config(:vsphere_dc)
216
216
  dc = vim.serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
217
217
 
218
- src_folder = find_folder(get_config(:folder)) || dc.vmFolder
218
+ src_folder = find_folder(get_config(:folder)) || dc.vmFolder
219
219
 
220
- src_vm = find_in_folder(src_folder, RbVmomi::VIM::VirtualMachine, config[:source_vm]) or
221
- abort "VM/Template not found"
220
+ src_vm = find_in_folder(src_folder, RbVmomi::VIM::VirtualMachine, config[:source_vm]) or
221
+ abort "VM/Template not found"
222
222
 
223
- clone_spec = generate_clone_spec(src_vm.config)
223
+ clone_spec = generate_clone_spec(src_vm.config)
224
224
 
225
225
  cust_folder = config[:dest_folder] || get_config(:folder)
226
226
 
227
- dest_folder = cust_folder.nil? ? src_vm.vmFolder : find_folder(cust_folder)
227
+ dest_folder = cust_folder.nil? ? src_vm.vmFolder : find_folder(cust_folder)
228
228
 
229
- task = src_vm.CloneVM_Task(:folder => dest_folder, :name => vmname, :spec => clone_spec)
230
- puts "Cloning template #{config[:source_vm]} to new VM #{vmname}"
231
- task.wait_for_completion
232
- puts "Finished creating virtual machine #{vmname}"
229
+ task = src_vm.CloneVM_Task(:folder => dest_folder, :name => vmname, :spec => clone_spec)
230
+ puts "Cloning template #{config[:source_vm]} to new VM #{vmname}"
231
+ task.wait_for_completion
232
+ puts "Finished creating virtual machine #{vmname}"
233
233
 
234
- if customization_plugin && customization_plugin.respond_to?(:reconfig_vm)
235
- target_vm = find_in_folder(dest_folder, RbVmomi::VIM::VirtualMachine, vmname) or abort "VM could not be found in #{dest_folder}"
236
- customization_plugin.reconfig_vm(target_vm)
237
- end
234
+ if customization_plugin && customization_plugin.respond_to?(:reconfig_vm)
235
+ target_vm = find_in_folder(dest_folder, RbVmomi::VIM::VirtualMachine, vmname) or abort "VM could not be found in #{dest_folder}"
236
+ customization_plugin.reconfig_vm(target_vm)
237
+ end
238
238
 
239
- if get_config(:power) || get_config(:bootstrap)
240
- vm = find_in_folder(dest_folder, RbVmomi::VIM::VirtualMachine, vmname) or
241
- fatal_exit("VM #{vmname} not found")
242
- vm.PowerOnVM_Task.wait_for_completion
243
- puts "Powered on virtual machine #{vmname}"
244
- end
239
+ if get_config(:power) || get_config(:bootstrap)
240
+ vm = find_in_folder(dest_folder, RbVmomi::VIM::VirtualMachine, vmname) or
241
+ fatal_exit("VM #{vmname} not found")
242
+ vm.PowerOnVM_Task.wait_for_completion
243
+ puts "Powered on virtual machine #{vmname}"
244
+ end
245
245
 
246
- if get_config(:bootstrap)
247
- sleep 2 until vm.guest.ipAddress
248
- config[:fqdn] = vm.guest.ipAddress unless config[:fqdn]
249
- print "Waiting for sshd..."
250
- print "." until tcp_test_ssh(config[:fqdn])
251
- puts "done"
246
+ if get_config(:bootstrap)
247
+ sleep 2 until vm.guest.ipAddress
248
+ config[:fqdn] = vm.guest.ipAddress unless config[:fqdn]
249
+ print "Waiting for sshd..."
250
+ print "." until tcp_test_ssh(config[:fqdn])
251
+ puts "done"
252
252
 
253
- bootstrap_for_node.run
254
- end
255
- end
253
+ bootstrap_for_node.run
254
+ end
255
+ end
256
256
 
257
- # Builds a CloneSpec
258
- def generate_clone_spec (src_config)
257
+ # Builds a CloneSpec
258
+ def generate_clone_spec (src_config)
259
259
 
260
260
  rspec = nil
261
261
  if get_config(:resource_pool)
@@ -268,219 +268,219 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
268
268
  rspec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => rp)
269
269
  end
270
270
 
271
- if get_config(:datastore)
272
- rspec.datastore = find_datastore(get_config(:datastore))
273
- end
274
-
275
- clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(:location => rspec,
276
- :powerOn => false,
277
- :template => false)
278
-
279
- clone_spec.config = RbVmomi::VIM.VirtualMachineConfigSpec(:deviceChange => Array.new)
280
-
281
- if get_config(:annotation)
282
- clone_spec.config.annotation = get_config(:annotation)
283
- end
284
-
285
- if get_config(:customization_cpucount)
286
- clone_spec.config.numCPUs = get_config(:customization_cpucount)
287
- end
288
-
289
- if get_config(:customization_memory)
290
- clone_spec.config.memoryMB = Integer(get_config(:customization_memory)) * 1024
291
- end
292
-
293
- if get_config(:customization_vlan)
294
- network = find_network(get_config(:customization_vlan))
295
- card = src_config.hardware.device.find { |d| d.deviceInfo.label == "Network adapter 1" } or
296
- abort "Can't find source network card to customize"
297
- begin
298
- switch_port = RbVmomi::VIM.DistributedVirtualSwitchPortConnection(:switchUuid => network.config.distributedVirtualSwitch.uuid ,:portgroupKey => network.key)
299
- card.backing.port = switch_port
300
- rescue
301
- # not connected to a distibuted switch?
302
- card.backing.deviceName = network.name
303
- end
304
- dev_spec = RbVmomi::VIM.VirtualDeviceConfigSpec(:device => card, :operation => "edit")
305
- clone_spec.config.deviceChange.push dev_spec
306
- end
307
-
308
- if get_config(:customization_spec)
309
- csi = find_customization(get_config(:customization_spec)) or
310
- fatal_exit("failed to find customization specification named #{get_config(:customization_spec)}")
311
-
312
- if csi.info.type != "Linux"
313
- fatal_exit("Only Linux customization specifications are currently supported")
314
- end
315
- cust_spec = csi.spec
316
- else
317
- global_ipset = RbVmomi::VIM.CustomizationGlobalIPSettings
318
- cust_spec = RbVmomi::VIM.CustomizationSpec(:globalIPSettings => global_ipset)
319
- end
320
-
321
- if get_config(:customization_dns_ips)
322
- cust_spec.globalIPSettings.dnsServerList = get_config(:customization_dns_ips).split(',')
323
- end
324
-
325
- if get_config(:customization_dns_suffixes)
326
- cust_spec.globalIPSettings.dnsSuffixList = get_config(:customization_dns_suffixes).split(',')
327
- end
328
-
329
- if config[:customization_ips]
330
- if get_config(:customization_gw)
331
- cust_spec.nicSettingMap = config[:customization_ips].split(',').map { |i| generate_adapter_map(i,get_config(:customization_gw)) }
332
- else
333
- cust_spec.nicSettingMap = config[:customization_ips].split(',').map { |i| generate_adapter_map(i) }
334
- end
335
- end
271
+ if get_config(:datastore)
272
+ rspec.datastore = find_datastore(get_config(:datastore))
273
+ end
274
+
275
+ clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(:location => rspec,
276
+ :powerOn => false,
277
+ :template => false)
278
+
279
+ clone_spec.config = RbVmomi::VIM.VirtualMachineConfigSpec(:deviceChange => Array.new)
280
+
281
+ if get_config(:annotation)
282
+ clone_spec.config.annotation = get_config(:annotation)
283
+ end
284
+
285
+ if get_config(:customization_cpucount)
286
+ clone_spec.config.numCPUs = get_config(:customization_cpucount)
287
+ end
288
+
289
+ if get_config(:customization_memory)
290
+ clone_spec.config.memoryMB = Integer(get_config(:customization_memory)) * 1024
291
+ end
292
+
293
+ if get_config(:customization_vlan)
294
+ network = find_network(get_config(:customization_vlan))
295
+ card = src_config.hardware.device.find { |d| d.deviceInfo.label == "Network adapter 1" } or
296
+ abort "Can't find source network card to customize"
297
+ begin
298
+ switch_port = RbVmomi::VIM.DistributedVirtualSwitchPortConnection(:switchUuid => network.config.distributedVirtualSwitch.uuid, :portgroupKey => network.key)
299
+ card.backing.port = switch_port
300
+ rescue
301
+ # not connected to a distibuted switch?
302
+ card.backing.deviceName = network.name
303
+ end
304
+ dev_spec = RbVmomi::VIM.VirtualDeviceConfigSpec(:device => card, :operation => "edit")
305
+ clone_spec.config.deviceChange.push dev_spec
306
+ end
307
+
308
+ if get_config(:customization_spec)
309
+ csi = find_customization(get_config(:customization_spec)) or
310
+ fatal_exit("failed to find customization specification named #{get_config(:customization_spec)}")
311
+
312
+ if csi.info.type != "Linux"
313
+ fatal_exit("Only Linux customization specifications are currently supported")
314
+ end
315
+ cust_spec = csi.spec
316
+ else
317
+ global_ipset = RbVmomi::VIM.CustomizationGlobalIPSettings
318
+ cust_spec = RbVmomi::VIM.CustomizationSpec(:globalIPSettings => global_ipset)
319
+ end
320
+
321
+ if get_config(:customization_dns_ips)
322
+ cust_spec.globalIPSettings.dnsServerList = get_config(:customization_dns_ips).split(',')
323
+ end
324
+
325
+ if get_config(:customization_dns_suffixes)
326
+ cust_spec.globalIPSettings.dnsSuffixList = get_config(:customization_dns_suffixes).split(',')
327
+ end
328
+
329
+ if config[:customization_ips]
330
+ if get_config(:customization_gw)
331
+ cust_spec.nicSettingMap = config[:customization_ips].split(',').map { |i| generate_adapter_map(i, get_config(:customization_gw)) }
332
+ else
333
+ cust_spec.nicSettingMap = config[:customization_ips].split(',').map { |i| generate_adapter_map(i) }
334
+ end
335
+ end
336
336
 
337
337
  unless get_config(:disable_customization)
338
338
  use_ident = !config[:customization_hostname].nil? || !get_config(:customization_domain).nil? || cust_spec.identity.nil?
339
339
 
340
340
 
341
- if use_ident
342
- # TODO - verify that we're deploying a linux spec, at least warn
343
- ident = RbVmomi::VIM.CustomizationLinuxPrep
344
-
345
- ident.hostName = RbVmomi::VIM.CustomizationFixedName
346
- if config[:customization_hostname]
347
- ident.hostName.name = config[:customization_hostname]
348
- else
349
- ident.hostName.name = config[:vmname]
350
- end
351
-
352
- if get_config(:customization_domain)
353
- ident.domain = get_config(:customization_domain)
354
- else
355
- ident.domain = ''
356
- end
357
-
358
- cust_spec.identity = ident
359
- end
360
-
361
- if customization_plugin && customization_plugin.respond_to?(:customize_clone_spec)
362
- clone_spec = customization_plugin.customize_clone_spec(src_config, clone_spec)
363
- end
364
-
365
- clone_spec.customization = cust_spec
366
- end
367
- clone_spec
368
- end
369
-
370
- # Loads the customization plugin if one was specified
371
- # @return [KnifeVspherePlugin] the loaded and initialized plugin or nil
372
- def customization_plugin
373
- if @customization_plugin.nil?
374
- if cplugin_path = get_config(:customization_plugin)
375
- if File.exists? cplugin_path
376
- require cplugin_path
377
- else
378
- abort "Customization plugin could not be found at #{cplugin_path}"
379
- end
380
-
381
- if Object.const_defined? 'KnifeVspherePlugin'
382
- @customization_plugin = Object.const_get('KnifeVspherePlugin').new
383
- if cplugin_data = get_config(:customization_plugin_data)
384
- if @customization_plugin.respond_to?(:data=)
385
- @customization_plugin.data = cplugin_data
386
- else
387
- abort "Customization plugin has no :data= accessor to receive the --cplugin-data argument. Define both or neither."
388
- end
389
- end
390
- else
391
- abort "KnifeVspherePlugin class is not defined in #{cplugin_path}"
392
- end
393
- end
394
- end
395
-
396
- @customization_plugin
397
- end
398
-
399
- # Retrieves a CustomizationSpecItem that matches the supplied name
400
- # @param vim [Connection] VI Connection to use
401
- # @param name [String] name of customization
402
- # @return [RbVmomi::VIM::CustomizationSpecItem]
403
- def find_customization(name)
404
- csm = config[:vim].serviceContent.customizationSpecManager
405
- csm.GetCustomizationSpec(:name => name)
406
- end
407
-
408
- # Generates a CustomizationAdapterMapping (currently only single IPv4 address) object
409
- # @param ip [String] Any static IP address to use, otherwise DHCP
410
- # @param gw [String] If static, the gateway for the interface, otherwise network address + 1 will be used
411
- # @return [RbVmomi::VIM::CustomizationIPSettings]
412
- def generate_adapter_map (ip=nil, gw=nil, dns1=nil, dns2=nil, domain=nil)
413
-
414
- settings = RbVmomi::VIM.CustomizationIPSettings
415
-
416
- if ip.nil?
417
- settings.ip = RbVmomi::VIM::CustomizationDhcpIpGenerator
418
- else
419
- cidr_ip = NetAddr::CIDR.create(ip)
420
- settings.ip = RbVmomi::VIM::CustomizationFixedIp(:ipAddress => cidr_ip.ip)
421
- settings.subnetMask = cidr_ip.netmask_ext
422
-
423
- # TODO - want to confirm gw/ip are in same subnet?
424
- # Only set gateway on first IP.
425
- if config[:customization_ips].split(',').first == ip
426
- if gw.nil?
427
- settings.gateway = [cidr_ip.network(:Objectify => true).next_ip]
428
- else
429
- gw_cidr = NetAddr::CIDR.create(gw)
430
- settings.gateway = [gw_cidr.ip]
431
- end
432
- end
433
- end
434
-
435
- adapter_map = RbVmomi::VIM.CustomizationAdapterMapping
436
- adapter_map.adapter = settings
437
- adapter_map
438
- end
439
-
440
- def bootstrap_for_node()
441
- Chef::Knife::Bootstrap.load_deps
442
- bootstrap = Chef::Knife::Bootstrap.new
443
- bootstrap.name_args = [config[:fqdn]]
444
- bootstrap.config[:run_list] = get_config(:run_list).split(/[\s,]+/)
341
+ if use_ident
342
+ # TODO - verify that we're deploying a linux spec, at least warn
343
+ ident = RbVmomi::VIM.CustomizationLinuxPrep
344
+
345
+ ident.hostName = RbVmomi::VIM.CustomizationFixedName
346
+ if config[:customization_hostname]
347
+ ident.hostName.name = config[:customization_hostname]
348
+ else
349
+ ident.hostName.name = config[:vmname]
350
+ end
351
+
352
+ if get_config(:customization_domain)
353
+ ident.domain = get_config(:customization_domain)
354
+ else
355
+ ident.domain = ''
356
+ end
357
+
358
+ cust_spec.identity = ident
359
+ end
360
+
361
+ if customization_plugin && customization_plugin.respond_to?(:customize_clone_spec)
362
+ clone_spec = customization_plugin.customize_clone_spec(src_config, clone_spec)
363
+ end
364
+
365
+ clone_spec.customization = cust_spec
366
+ end
367
+ clone_spec
368
+ end
369
+
370
+ # Loads the customization plugin if one was specified
371
+ # @return [KnifeVspherePlugin] the loaded and initialized plugin or nil
372
+ def customization_plugin
373
+ if @customization_plugin.nil?
374
+ if cplugin_path = get_config(:customization_plugin)
375
+ if File.exists? cplugin_path
376
+ require cplugin_path
377
+ else
378
+ abort "Customization plugin could not be found at #{cplugin_path}"
379
+ end
380
+
381
+ if Object.const_defined? 'KnifeVspherePlugin'
382
+ @customization_plugin = Object.const_get('KnifeVspherePlugin').new
383
+ if cplugin_data = get_config(:customization_plugin_data)
384
+ if @customization_plugin.respond_to?(:data=)
385
+ @customization_plugin.data = cplugin_data
386
+ else
387
+ abort "Customization plugin has no :data= accessor to receive the --cplugin-data argument. Define both or neither."
388
+ end
389
+ end
390
+ else
391
+ abort "KnifeVspherePlugin class is not defined in #{cplugin_path}"
392
+ end
393
+ end
394
+ end
395
+
396
+ @customization_plugin
397
+ end
398
+
399
+ # Retrieves a CustomizationSpecItem that matches the supplied name
400
+ # @param vim [Connection] VI Connection to use
401
+ # @param name [String] name of customization
402
+ # @return [RbVmomi::VIM::CustomizationSpecItem]
403
+ def find_customization(name)
404
+ csm = config[:vim].serviceContent.customizationSpecManager
405
+ csm.GetCustomizationSpec(:name => name)
406
+ end
407
+
408
+ # Generates a CustomizationAdapterMapping (currently only single IPv4 address) object
409
+ # @param ip [String] Any static IP address to use, otherwise DHCP
410
+ # @param gw [String] If static, the gateway for the interface, otherwise network address + 1 will be used
411
+ # @return [RbVmomi::VIM::CustomizationIPSettings]
412
+ def generate_adapter_map (ip=nil, gw=nil, dns1=nil, dns2=nil, domain=nil)
413
+
414
+ settings = RbVmomi::VIM.CustomizationIPSettings
415
+
416
+ if ip.nil?
417
+ settings.ip = RbVmomi::VIM::CustomizationDhcpIpGenerator
418
+ else
419
+ cidr_ip = NetAddr::CIDR.create(ip)
420
+ settings.ip = RbVmomi::VIM::CustomizationFixedIp(:ipAddress => cidr_ip.ip)
421
+ settings.subnetMask = cidr_ip.netmask_ext
422
+
423
+ # TODO - want to confirm gw/ip are in same subnet?
424
+ # Only set gateway on first IP.
425
+ if config[:customization_ips].split(',').first == ip
426
+ if gw.nil?
427
+ settings.gateway = [cidr_ip.network(:Objectify => true).next_ip]
428
+ else
429
+ gw_cidr = NetAddr::CIDR.create(gw)
430
+ settings.gateway = [gw_cidr.ip]
431
+ end
432
+ end
433
+ end
434
+
435
+ adapter_map = RbVmomi::VIM.CustomizationAdapterMapping
436
+ adapter_map.adapter = settings
437
+ adapter_map
438
+ end
439
+
440
+ def bootstrap_for_node()
441
+ Chef::Knife::Bootstrap.load_deps
442
+ bootstrap = Chef::Knife::Bootstrap.new
443
+ bootstrap.name_args = [config[:fqdn]]
444
+ bootstrap.config[:run_list] = get_config(:run_list).split(/[\s,]+/)
445
445
  bootstrap.config[:secret_file] = get_config(:secret_file)
446
446
  bootstrap.config[:ssh_user] = get_config(:ssh_user)
447
- bootstrap.config[:ssh_password] = get_config(:ssh_password)
448
- bootstrap.config[:ssh_port] = get_config(:ssh_port)
449
- bootstrap.config[:identity_file] = get_config(:identity_file)
450
- bootstrap.config[:chef_node_name] = get_config(:chef_node_name)
451
- bootstrap.config[:prerelease] = get_config(:prerelease)
452
- bootstrap.config[:bootstrap_version] = get_config(:bootstrap_version)
453
- bootstrap.config[:distro] = get_config(:distro)
454
- bootstrap.config[:use_sudo] = true unless get_config(:ssh_user) == 'root'
455
- bootstrap.config[:template_file] = get_config(:template_file)
456
- bootstrap.config[:environment] = get_config(:environment)
447
+ bootstrap.config[:ssh_password] = get_config(:ssh_password)
448
+ bootstrap.config[:ssh_port] = get_config(:ssh_port)
449
+ bootstrap.config[:identity_file] = get_config(:identity_file)
450
+ bootstrap.config[:chef_node_name] = get_config(:chef_node_name)
451
+ bootstrap.config[:prerelease] = get_config(:prerelease)
452
+ bootstrap.config[:bootstrap_version] = get_config(:bootstrap_version)
453
+ bootstrap.config[:distro] = get_config(:distro)
454
+ bootstrap.config[:use_sudo] = true unless get_config(:ssh_user) == 'root'
455
+ bootstrap.config[:template_file] = get_config(:template_file)
456
+ bootstrap.config[:environment] = get_config(:environment)
457
457
  bootstrap.config[:first_boot_attributes] = get_config(:first_boot_attributes)
458
458
  bootstrap.config[:log_level] = get_config(:log_level)
459
- # may be needed for vpc_mode
460
- bootstrap.config[:no_host_key_verify] = get_config(:no_host_key_verify)
461
- bootstrap
462
- end
463
-
464
- def tcp_test_ssh(hostname)
465
- tcp_socket = TCPSocket.new(hostname, get_config(:ssh_port))
466
- readable = IO.select([tcp_socket], nil, nil, 5)
467
- if readable
468
- Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
469
- true
470
- else
471
- false
472
- end
473
- rescue Errno::ETIMEDOUT
474
- false
475
- rescue Errno::EPERM
476
- false
477
- rescue Errno::ECONNREFUSED
478
- sleep 2
479
- false
480
- rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH
481
- sleep 2
482
- false
483
- ensure
484
- tcp_socket && tcp_socket.close
485
- end
459
+ # may be needed for vpc_mode
460
+ bootstrap.config[:no_host_key_verify] = get_config(:no_host_key_verify)
461
+ bootstrap
462
+ end
463
+
464
+ def tcp_test_ssh(hostname)
465
+ tcp_socket = TCPSocket.new(hostname, get_config(:ssh_port))
466
+ readable = IO.select([tcp_socket], nil, nil, 5)
467
+ if readable
468
+ Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
469
+ true
470
+ else
471
+ false
472
+ end
473
+ rescue Errno::ETIMEDOUT
474
+ false
475
+ rescue Errno::EPERM
476
+ false
477
+ rescue Errno::ECONNREFUSED
478
+ sleep 2
479
+ false
480
+ rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH
481
+ sleep 2
482
+ false
483
+ ensure
484
+ tcp_socket && tcp_socket.close
485
+ end
486
486
  end