wombat-cli 0.3.4 → 0.4.0

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/.travis.yml +27 -0
  4. data/CHANGELOG.md +15 -1
  5. data/Gemfile +3 -0
  6. data/README.md +2 -2
  7. data/Rakefile +25 -0
  8. data/bin/wombat +1 -1
  9. data/generator_files/cookbooks/automate/metadata.rb +1 -1
  10. data/generator_files/cookbooks/automate/recipes/update-users.rb +1 -1
  11. data/generator_files/cookbooks/chef_server/recipes/default.rb +24 -11
  12. data/generator_files/cookbooks/workstation/.kitchen.ec2.yml +2 -1
  13. data/generator_files/cookbooks/workstation/metadata.rb +1 -1
  14. data/generator_files/cookbooks/workstation/recipes/default.rb +1 -2
  15. data/generator_files/cookbooks/workstation/templates/default/ise_profile.ps1.erb +2 -2
  16. data/generator_files/cookbooks/workstation/test/integration/default/workstation_spec.rb +4 -4
  17. data/generator_files/packer/automate.json +129 -107
  18. data/generator_files/packer/build-node.json +134 -112
  19. data/generator_files/packer/chef-server.json +130 -108
  20. data/generator_files/packer/compliance.json +126 -104
  21. data/generator_files/packer/infranodes-windows.json +136 -97
  22. data/generator_files/packer/infranodes.json +127 -106
  23. data/generator_files/packer/workstation.json +134 -95
  24. data/generator_files/templates/arm.json.erb +576 -0
  25. data/generator_files/wombat.yml +6 -2
  26. data/lib/wombat/aws.rb +67 -0
  27. data/lib/wombat/build.rb +273 -184
  28. data/lib/wombat/cli.rb +182 -147
  29. data/lib/wombat/common.rb +228 -220
  30. data/lib/wombat/crypto.rb +65 -0
  31. data/lib/wombat/delete.rb +48 -18
  32. data/lib/wombat/deploy.rb +147 -34
  33. data/lib/wombat/init.rb +21 -19
  34. data/lib/wombat/latest.rb +27 -0
  35. data/lib/wombat/output.rb +31 -30
  36. data/lib/wombat/update.rb +13 -10
  37. data/lib/wombat/version.rb +1 -1
  38. data/spec/functional/common_spec.rb +26 -0
  39. data/spec/spec_helper.rb +103 -0
  40. data/spec/unit/common_spec.rb +116 -0
  41. data/wombat-cli.gemspec +2 -1
  42. metadata +36 -11
  43. /data/generator_files/cookbooks/workstation/test/fixtures/cookbooks/mock_data/files/{delivery.crt → automate.crt} +0 -0
  44. /data/generator_files/cookbooks/workstation/test/fixtures/cookbooks/mock_data/files/{delivery.key → automate.key} +0 -0
  45. /data/generator_files/cookbooks/workstation/test/fixtures/cookbooks/mock_data/files/{chef-server.crt → chef.crt} +0 -0
  46. /data/generator_files/cookbooks/workstation/test/fixtures/cookbooks/mock_data/files/{chef-server.key → chef.key} +0 -0
data/lib/wombat/build.rb CHANGED
@@ -1,231 +1,320 @@
1
1
 
2
2
  require 'wombat/common'
3
+ require 'wombat/crypto'
3
4
  require 'mixlib/shellout'
4
5
  require 'parallel'
6
+ require 'ms_rest_azure'
7
+ require 'azure_mgmt_resources'
8
+ require 'azure_mgmt_storage'
5
9
 
6
- class BuildRunner
10
+ module Wombat
11
+ class BuildRunner
12
+ include Wombat::Common
13
+ include Wombat::Crypto
7
14
 
8
- include Common
15
+ attr_reader :templates, :builder, :parallel
9
16
 
10
- attr_reader :templates, :builder, :parallel
17
+ def initialize(opts)
18
+ @templates = opts.templates.nil? ? calculate_templates : opts.templates
19
+ @builder = opts.builder.nil? ? "amazon-ebs" : opts.builder
20
+ @parallel = opts.parallel
21
+ @wombat_yml = opts.wombat_yml unless opts.wombat_yml.nil?
22
+ @debug = opts.debug
23
+ @no_vendor = opts.vendor
24
+ end
11
25
 
12
- def initialize(opts)
13
- @templates = opts.templates.nil? ? calculate_templates : opts.templates
14
- @builder = opts.builder.nil? ? "amazon-ebs" : opts.builder
15
- @parallel = opts.parallel
16
- end
26
+ def start
27
+ if which('packer').nil?
28
+ raise "packer binary not found in path, exiting..."
29
+ end
30
+ banner("Generating certs (if necessary)")
31
+ wombat['certs'].each do |hostname|
32
+ gen_x509_cert(hostname)
33
+ end
34
+ banner("Generating SSH keypair (if necessary)")
35
+ gen_ssh_key
17
36
 
18
- def start
19
- if which('packer').nil?
20
- raise "packer binary not found in path, exiting..."
21
- end
22
- banner("Generating certs (if necessary)")
23
- wombat['certs'].each do |hostname|
24
- gen_x509_cert(hostname)
37
+ # If running on azure ensure that the resource group and storage account exist
38
+ prepare_azure if builder == "azure-arm"
39
+
40
+ time = Benchmark.measure do
41
+ banner("Starting build for templates: #{templates}")
42
+ aws_region_check if builder == 'amazon-ebs'
43
+ templates.each do |t|
44
+ vendor_cookbooks(t) unless @no_vendor
45
+ end
46
+
47
+ if parallel.nil?
48
+ build_hash.each do |k, v|
49
+ build(v['template'], v['options'])
50
+ end
51
+ else
52
+ build_parallel(templates)
53
+ end
54
+ end
55
+ shell_out_command("say -v fred \"Wombat has made an #{build_hash.keys}\" for you") if audio?
56
+ banner("Build finished in #{duration(time.real)}.")
25
57
  end
26
- banner("Generating SSH keypair (if necessary)")
27
- gen_ssh_key
28
58
 
29
- time = Benchmark.measure do
30
- banner("Starting build for templates: #{templates}")
31
- aws_region_check if builder == 'amazon-ebs'
32
- templates.each do |t|
33
- vendor_cookbooks(t)
59
+ private
60
+
61
+ def prepare_azure()
62
+
63
+ # Ensure that a storage acocunt has been specified, if it has not error
64
+ if wombat['azure']['storage_account'].nil?
65
+ puts "\nA storage account name must be specified in wombat.yml, e.g.\n openssl rand -base64 12\nEnsure all lowercase and no special characters"
66
+ exit
34
67
  end
35
68
 
36
- if parallel.nil?
37
- build_hash.each do |k, v|
38
- build(v['template'], v['options'])
39
- end
69
+ # Using environment variables connect to azure
70
+ subscription_id = ENV['AZURE_SUBSCRIPTION_ID']
71
+ tenant_id = ENV['AZURE_TENANT_ID']
72
+ client_id = ENV['AZURE_CLIENT_ID']
73
+ client_secret = ENV['AZURE_CLIENT_SECRET']
74
+
75
+ token_provider = MsRestAzure::ApplicationTokenProvider.new(tenant_id, client_id, client_secret)
76
+ azure_conn = MsRest::TokenCredentials.new(token_provider)
77
+
78
+ # Create a resource to create the resource group if it does not exist
79
+ resource_management_client = Azure::ARM::Resources::ResourceManagementClient.new(azure_conn)
80
+ resource_management_client.subscription_id = subscription_id
81
+
82
+ # Create a storage account client to create the stoarge account if it does not exist
83
+ storage_management_client = Azure::ARM::Storage::StorageManagementClient.new(azure_conn)
84
+ storage_management_client.subscription_id = subscription_id
85
+
86
+ # Check that the resource group exists
87
+ banner(format("Checking for resource group: %s", wombat['name']))
88
+ status = resource_management_client.resource_groups.check_existence(wombat['name'])
89
+ if status
90
+ puts "resource group already exists"
40
91
  else
41
- build_parallel(templates)
92
+ puts format("creating new resource group in '%s'", wombat['azure']['location'])
93
+
94
+ # Set the parameters for the resource group
95
+ resource_group = Azure::ARM::Resources::Models::ResourceGroup.new
96
+ resource_group.location = wombat['azure']['location']
97
+
98
+ # Create hash to be used as tags on the resource group
99
+ tags = {
100
+ InUse: "true",
101
+ owner: ENV['USER']
102
+ }
103
+
104
+ # If an owner has been specified in the wombat file override the owner value
105
+ if wombat.key?('owner') && !wombat['owner'].nil?
106
+ tags[:owner] = wombat['owner']
107
+ end
108
+
109
+ # add the tags hash to the parameters
110
+ resource_group.tags = tags
111
+
112
+ # Create the resource group
113
+ resource_management_client.resource_groups.create_or_update(wombat['name'], resource_group)
42
114
  end
43
- end
44
- shell_out_command("say -v fred \"Wombat has made an #{build_hash.keys.to_s}\" for you") if audio?
45
- banner("Build finished in #{duration(time.real)}.")
46
- end
47
115
 
48
- private
116
+ # Check to see if the storage account already exists
117
+ banner(format("Checking for storage account: %s", wombat['azure']['storage_account']))
49
118
 
50
- def build(template, options)
51
- bootstrap_aws if options['os'] == 'windows'
52
- shell_out_command(packer_build_cmd(template, builder, options))
53
- end
119
+ # Create the storage account in the resource group
120
+ # NOTE: This should have a test to see if the storage account exists and it available however the
121
+ # Azure Ruby SDK has an issue with the check_name_availability method and comes back with an error
122
+ # This would normally be done through an ARM template, but in this case needs to exist before Packer can run
123
+ storage_account = Azure::ARM::Storage::Models::StorageAccountCreateParameters.new
124
+ storage_account.location = wombat['azure']['location']
125
+ sku = Azure::ARM::Storage::Models::Sku.new
126
+ sku.name = 'Standard_LRS'
127
+ storage_account.sku = sku
128
+ storage_account.kind = Azure::ARM::Storage::Models::Kind::Storage
129
+
130
+ storage_management_client.storage_accounts.create(wombat['name'], wombat['azure']['storage_account'], storage_account)
54
131
 
55
- def build_parallel(templates)
56
- Parallel.map(build_hash.keys, in_threads: build_hash.count) do |name|
57
- build(build_hash[name]['template'], build_hash[name]['options'])
58
132
  end
59
- end
60
133
 
61
- def build_hash
62
- proc_hash = {}
63
- templates.each do |template_name|
64
- if template_name =~ /infranodes/
65
- infranodes.each do |name, _rl|
66
- next if name.empty?
67
- proc_hash[name] = {
68
- 'template' => template_name,
69
- 'options' => {
70
- 'node-name' => name,
71
- 'os' => wombat['infranodes'][name]['platform']
134
+ def build(template, options)
135
+ bootstrap_aws if options['os'] == 'windows'
136
+ shell_out_command(packer_build_cmd(template, builder, options))
137
+ end
138
+
139
+ def build_parallel(templates)
140
+ Parallel.map(build_hash.keys, in_threads: build_hash.count) do |name|
141
+ build(build_hash[name]['template'], build_hash[name]['options'])
142
+ end
143
+ end
144
+
145
+ def build_hash
146
+ proc_hash = {}
147
+ templates.each do |template_name|
148
+ if template_name =~ /infranodes/
149
+ infranodes.each do |name, _rl|
150
+ next if name.empty?
151
+ proc_hash[name] = {
152
+ 'template' => template_name,
153
+ 'options' => {
154
+ 'node-name' => name,
155
+ 'os' => wombat['infranodes'][name]['platform']
156
+ }
72
157
  }
73
- }
74
- end
75
- elsif template_name =~ /build-node/
76
- build_nodes.each do |name, num|
77
- proc_hash[name] = {
78
- 'template' => template_name,
79
- 'options' => {
80
- 'node-number' => num
158
+ end
159
+ elsif template_name =~ /build-node/
160
+ build_nodes.each do |name, num|
161
+ proc_hash[name] = {
162
+ 'template' => template_name,
163
+ 'options' => {
164
+ 'node-number' => num
165
+ }
81
166
  }
82
- }
83
- end
84
- elsif template_name =~ /workstation/
85
- workstations.each do |name, num|
86
- proc_hash[name] = {
87
- 'template' => template_name,
88
- 'options' => {
89
- 'os' => wombat['workstations']['platform'],
90
- 'workstation-number' => num
167
+ end
168
+ elsif template_name =~ /workstation/
169
+ workstations.each do |name, num|
170
+ proc_hash[name] = {
171
+ 'template' => template_name,
172
+ 'options' => {
173
+ 'os' => wombat['workstations']['platform'],
174
+ 'workstation-number' => num
175
+ }
91
176
  }
177
+ end
178
+ else
179
+ proc_hash[template_name] = {
180
+ 'template' => template_name,
181
+ 'options' => {}
92
182
  }
93
183
  end
94
- else
95
- proc_hash[template_name] = {
96
- 'template' => template_name,
97
- 'options' => {}
98
- }
99
184
  end
185
+ proc_hash
100
186
  end
101
- proc_hash
102
- end
103
187
 
104
- def a_to_s(*args)
105
- clean_array(*args).join(" ")
106
- end
107
-
108
- def clean_array(*args)
109
- args.flatten.reject { |i| i.nil? || i == "" }.map(&:to_s)
110
- end
111
-
112
- def b_to_c(builder)
113
- case builder
114
- when 'amazon-ebs'
115
- cloud = 'aws'
116
- when 'googlecompute'
117
- cloud = 'gce'
188
+ def a_to_s(*args)
189
+ clean_array(*args).join(" ")
118
190
  end
119
- end
120
191
 
121
- def shell_out_command(command)
122
- cmd = Mixlib::ShellOut.new(a_to_s(command), :timeout => conf['timeout'], live_stream: STDOUT)
123
- cmd.run_command
124
- cmd
125
- end
192
+ def clean_array(*args)
193
+ args.flatten.reject { |i| i.nil? || i == "" }.map(&:to_s)
194
+ end
126
195
 
127
- def aws_region_check
128
- if ENV['AWS_REGION']
129
- banner("Region set by environment: #{ENV['AWS_REGION']}")
130
- else
131
- banner("$AWS_REGION not set, setting to #{wombat['aws']['region']}")
132
- ENV['AWS_REGION'] = wombat['aws']['region']
196
+ def b_to_c(builder)
197
+ case builder
198
+ when 'amazon-ebs'
199
+ 'aws'
200
+ when 'googlecompute'
201
+ 'gce'
202
+ when 'azure-arm'
203
+ 'azure'
204
+ end
133
205
  end
134
- end
135
206
 
136
- def vendor_cookbooks(template)
137
- banner "Vendoring cookbooks for #{template}"
207
+ def shell_out_command(command)
208
+ cmd = Mixlib::ShellOut.new(a_to_s(command), :timeout => conf['timeout'], live_stream: STDOUT)
209
+ cmd.run_command
210
+ cmd
211
+ end
138
212
 
139
- if template =~ /.*-windows/
140
- base = template.split('-')[0]
141
- else
142
- base = template.split('.json')[0].tr('-', '_')
213
+ def aws_region_check
214
+ if ENV['AWS_REGION']
215
+ banner("Region set by environment: #{ENV['AWS_REGION']}")
216
+ else
217
+ banner("$AWS_REGION not set, setting to #{wombat['aws']['region']}")
218
+ ENV['AWS_REGION'] = wombat['aws']['region']
219
+ end
143
220
  end
144
- rm_cmd = "rm -rf #{conf['cookbook_dir']}/#{base}/Berksfile.lock vendored-cookbooks/#{base}"
145
- shell_out_command(rm_cmd)
146
- vendor_cmd = "berks vendor -q -b #{conf['cookbook_dir']}/#{base}/Berksfile vendored-cookbooks/#{base}"
147
- shell_out_command(vendor_cmd)
148
- end
149
221
 
150
- def log(template, builder, options)
151
- cloud = b_to_c(builder)
152
- case template
153
- when /automate/
154
- log_name = "#{cloud}-automate-#{linux}"
155
- when /chef-server/
156
- log_name = "#{cloud}-chef-server-#{linux}"
157
- when /compliance/
158
- log_name = "#{cloud}-compliance-#{linux}"
159
- when /build-node/
160
- log_name = "#{cloud}-build-node-#{options['node-number']}-#{linux}"
161
- when /workstation/
162
- log_name = "#{cloud}-workstation-#{options['workstation-number']}-#{linux}"
163
- when /infranodes/
164
- if options['os'] =~ /windows/
165
- log_name = "#{cloud}-infranodes-#{options['node-name']}-windows"
222
+ def vendor_cookbooks(template)
223
+ banner "Vendoring cookbooks for #{template}"
224
+
225
+ if template =~ /.*-windows/
226
+ base = template.split('-')[0]
166
227
  else
167
- log_name = "#{cloud}-infranodes-#{options['node-name']}-#{linux}"
228
+ base = template.split('.json')[0].tr('-', '_')
168
229
  end
230
+ rm_cmd = "rm -rf #{conf['cookbook_dir']}/#{base}/Berksfile.lock vendored-cookbooks/#{base}"
231
+ shell_out_command(rm_cmd)
232
+ vendor_cmd = "berks vendor -q -b #{conf['cookbook_dir']}/#{base}/Berksfile vendored-cookbooks/#{base}"
233
+ shell_out_command(vendor_cmd)
169
234
  end
170
- log_file = "#{conf['log_dir']}/#{log_name}.log"
171
- end
172
235
 
173
- def which(cmd)
174
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
175
- ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
176
- exts.each { |ext|
177
- exe = File.join(path, "#{cmd}#{ext}")
178
- return exe if File.executable?(exe) && !File.directory?(exe)
179
- }
236
+ def log(template, builder, options)
237
+ cloud = b_to_c(builder)
238
+ case template
239
+ when /automate/
240
+ log_name = "#{cloud}-automate-#{linux}"
241
+ when /chef-server/
242
+ log_name = "#{cloud}-chef-server-#{linux}"
243
+ when /compliance/
244
+ log_name = "#{cloud}-compliance-#{linux}"
245
+ when /build-node/
246
+ log_name = "#{cloud}-build-node-#{options['node-number']}-#{linux}"
247
+ when /workstation/
248
+ log_name = "#{cloud}-workstation-#{options['workstation-number']}-#{linux}"
249
+ when /infranodes/
250
+ if options['os'] =~ /windows/
251
+ log_name = "#{cloud}-infranodes-#{options['node-name']}-windows"
252
+ else
253
+ log_name = "#{cloud}-infranodes-#{options['node-name']}-#{linux}"
254
+ end
255
+ end
256
+ log_file = "#{conf['log_dir']}/#{log_name}.log"
180
257
  end
181
- return nil
182
- end
183
258
 
184
- def packer_build_cmd(template, builder, options)
185
- create_infranodes_json
259
+ def which(cmd)
260
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
261
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
262
+ exts.each { |ext|
263
+ exe = File.join(path, "#{cmd}#{ext}")
264
+ return exe if File.executable?(exe) && !File.directory?(exe)
265
+ }
266
+ end
267
+ return nil
268
+ end
186
269
 
187
- if template =~ /workstation/
188
- source_ami = wombat['aws']['source_ami']['windows']
189
- source_image = wombat['gce']['source_image']['windows']
190
- elsif template =~ /infranodes/
191
- if options['os'] == 'windows'
192
- source_ami = wombat['aws']['source_ami']['windows']
193
- source_image = wombat['gce']['source_image']['windows']
270
+ def base_image(template, builder)
271
+ cloud = b_to_c(builder)
272
+ if template =~ /workstation/
273
+ wombat[cloud]['source_image']['windows']
274
+ elsif template =~ /infranodes/
275
+ if options['os'] == 'windows'
276
+ wombat[cloud]['source_image']['windows']
277
+ else
278
+ wombat[cloud]['source_image'][linux]
279
+ end
194
280
  else
195
- source_ami = wombat['aws']['source_ami'][linux]
196
- source_image = wombat['gce']['source_image'][linux]
281
+ wombat[cloud]['source_image'][linux]
197
282
  end
198
- else
199
- source_ami = wombat['aws']['source_ami'][linux]
200
- source_image = wombat['gce']['source_image'][linux]
201
- end
202
-
203
- Dir.mkdir(conf['log_dir'], 0755) unless File.exist?(conf['log_dir'])
204
-
205
- cmd = %W(packer build #{conf['packer_dir']}/#{template}.json | tee #{log(template, builder, options)})
206
- cmd.insert(2, "--only #{builder}")
207
- cmd.insert(2, "--var org=#{wombat['org']}")
208
- cmd.insert(2, "--var domain=#{wombat['domain']}")
209
- cmd.insert(2, "--var domain_prefix=#{wombat['domain_prefix']}")
210
- cmd.insert(2, "--var enterprise=#{wombat['enterprise']}")
211
- cmd.insert(2, "--var chefdk=#{wombat['products']['chefdk']}")
212
- cmd.insert(2, "--var chef_ver=#{wombat['products']['chef'].split('-')[1]}")
213
- cmd.insert(2, "--var chef_channel=#{wombat['products']['chef'].split('-')[0]}")
214
- cmd.insert(2, "--var automate=#{wombat['products']['automate']}")
215
- cmd.insert(2, "--var compliance=#{wombat['products']['compliance']}")
216
- cmd.insert(2, "--var chef-server=#{wombat['products']['chef-server']}")
217
- cmd.insert(2, "--var push-jobs-server=#{wombat['products']['push-jobs-server']}")
218
- cmd.insert(2, "--var manage=#{wombat['products']['manage']}")
219
- cmd.insert(2, "--var node-name=#{options['node-name']}") if template =~ /infranodes/
220
- cmd.insert(2, "--var node-number=#{options['node-number']}") if template =~ /build-node/
221
- cmd.insert(2, "--var build-nodes=#{wombat['build-nodes']['count']}")
222
- cmd.insert(2, "--var winrm_password=#{wombat['workstations']['password']}")
223
- cmd.insert(2, "--var winrm_username=Administrator")
224
- cmd.insert(2, "--var workstation-number=#{options['workstation-number']}") if template =~ /workstation/
225
- cmd.insert(2, "--var workstations=#{wombat['workstations']['count']}")
226
- cmd.insert(2, "--var aws_source_ami=#{source_ami}")
227
- cmd.insert(2, "--var gce_source_image=#{source_image}")
228
- cmd.insert(2, "--var ssh_username=#{linux}")
229
- cmd.join(' ')
283
+ end
284
+
285
+ def packer_build_cmd(template, builder, options)
286
+ create_infranodes_json
287
+ Dir.mkdir(conf['log_dir'], 0755) unless File.exist?(conf['log_dir'])
288
+
289
+ cmd = %W(packer build #{conf['packer_dir']}/#{template}.json | tee #{log(template, builder, options)})
290
+ cmd.insert(2, "--only #{builder}")
291
+ cmd.insert(2, "--var org=#{wombat['org']}")
292
+ cmd.insert(2, "--var domain=#{wombat['domain']}")
293
+ cmd.insert(2, "--var domain_prefix=#{wombat['domain_prefix']}")
294
+ cmd.insert(2, "--var enterprise=#{wombat['enterprise']}")
295
+ cmd.insert(2, "--var chefdk=#{wombat['products']['chefdk']}")
296
+ cmd.insert(2, "--var chef_ver=#{wombat['products']['chef'].split('-')[1]}")
297
+ cmd.insert(2, "--var chef_channel=#{wombat['products']['chef'].split('-')[0]}")
298
+ cmd.insert(2, "--var automate=#{wombat['products']['automate']}")
299
+ cmd.insert(2, "--var compliance=#{wombat['products']['compliance']}")
300
+ cmd.insert(2, "--var chef-server=#{wombat['products']['chef-server']}")
301
+ cmd.insert(2, "--var push-jobs-server=#{wombat['products']['push-jobs-server']}")
302
+ cmd.insert(2, "--var manage=#{wombat['products']['manage']}")
303
+ cmd.insert(2, "--var node-name=#{options['node-name']}") if template =~ /infranodes/
304
+ cmd.insert(2, "--var node-number=#{options['node-number']}") if template =~ /build-node/
305
+ cmd.insert(2, "--var build-nodes=#{wombat['build-nodes']['count']}")
306
+ cmd.insert(2, "--var winrm_password=#{wombat['workstations']['password']}")
307
+ cmd.insert(2, "--var winrm_username=Administrator")
308
+ cmd.insert(2, "--var workstation-number=#{options['workstation-number']}") if template =~ /workstation/
309
+ cmd.insert(2, "--var workstations=#{wombat['workstations']['count']}")
310
+ cmd.insert(2, "--var aws_source_ami=#{base_image(template, builder)}") if builder =~ /amazon-ebs/
311
+ cmd.insert(2, "--var gce_source_image=#{base_image(template, builder)}") if builder =~ /googlecompute/
312
+ cmd.insert(2, "--var azure_location=#{wombat['azure']['location']}")
313
+ cmd.insert(2, "--var ssh_username=#{linux}")
314
+ cmd.insert(2, "--var azure_resource_group=#{wombat['name']}")
315
+ cmd.insert(2, "--var azure_storage_account=#{wombat['azure']['storage_account']}")
316
+ cmd.insert(2, "--debug") if @debug
317
+ cmd.join(' ')
318
+ end
230
319
  end
231
320
  end