vagrant-softlayer 0.2.0 → 0.3.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.
@@ -0,0 +1,408 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'getoptlong'
4
+ require 'tmpdir'
5
+
6
+ require 'rubygems'
7
+ require 'softlayer_api'
8
+
9
+ $sl = {
10
+ :data => {
11
+ :create_opts => nil,
12
+ :private_images => nil,
13
+ :public_images => nil
14
+ },
15
+ :service => {
16
+ :account => nil,
17
+ :virtual_guest => nil,
18
+ :virtual_guest_block_device_template_group => nil
19
+ },
20
+ :sl_credentials => {
21
+ :api_key => nil,
22
+ :endpoint_url => SoftLayer::API_PUBLIC_ENDPOINT,
23
+ :username => nil
24
+ }
25
+ }
26
+
27
+ $boxes = {
28
+ :data => {},
29
+ :datacenter => nil,
30
+ :dir => {
31
+ :boxes => "boxes",
32
+ :vagrantfiles => "vagrantfiles",
33
+ :boxes_root => nil,
34
+ :output_root => File.expand_path("."),
35
+ :vagrantfiles_root => nil
36
+ },
37
+ :domain => nil,
38
+ :file_templates => {
39
+ :created_by => "# vagrant-softlayer-boxes automatic template export",
40
+ :end => "end",
41
+ :image_detail => "# Compute or flex image details:",
42
+ :indent => Hash.new() { |hash, key| hash[key] = " " * key },
43
+ :metadata_json => "{\"provider\": \"softlayer\"}",
44
+ :os_templates_avail => "# Available versions of this OS template (based on VM property selections):",
45
+ :sl_config_start => "config.vm.provider :softlayer do |sl|",
46
+ :vagrant_config_start => "Vagrant.configure(\"2\") do |config|"
47
+ },
48
+ :filter => nil,
49
+ :images => {
50
+ :private => true,
51
+ :public => true
52
+ },
53
+ :metadata_path => nil,
54
+ :monthly_billing => nil,
55
+ :templates => true,
56
+ :vlan_private => nil,
57
+ :vlan_public => nil
58
+ }
59
+
60
+ def procCliOptions()
61
+ opts = GetoptLong.new(
62
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
63
+ [ '--output_dir', '-o', GetoptLong::REQUIRED_ARGUMENT ],
64
+ [ '--only_images', '-i', GetoptLong::NO_ARGUMENT ],
65
+ [ '--only_private_images', '-p', GetoptLong::NO_ARGUMENT ],
66
+ [ '--only_public_images', '-g', GetoptLong::NO_ARGUMENT ],
67
+ [ '--only_templates', '-t', GetoptLong::NO_ARGUMENT ],
68
+ [ '--default_domain', GetoptLong::REQUIRED_ARGUMENT ],
69
+ [ '--default_datacenter', GetoptLong::REQUIRED_ARGUMENT ],
70
+ [ '--default_monthly_billing', GetoptLong::NO_ARGUMENT ],
71
+ [ '--default_vlan_private', GetoptLong::REQUIRED_ARGUMENT ],
72
+ [ '--default_vlan_public', GetoptLong::REQUIRED_ARGUMENT ],
73
+ [ '--sl_api_key', '-k', GetoptLong::REQUIRED_ARGUMENT ],
74
+ [ '--sl_endpoint_url', '-e', GetoptLong::REQUIRED_ARGUMENT ],
75
+ [ '--sl_username','-u', GetoptLong::REQUIRED_ARGUMENT ]
76
+ )
77
+
78
+ opts.each do | opt, optval |
79
+ case opt
80
+ when '--help'
81
+ puts <<-EOF
82
+ vagrant-softlayer-boxes [OPTION] [FILTER]
83
+
84
+ --help, -h:
85
+ Print this help.
86
+
87
+ --sl_username USERNAME, -u USERNAME:
88
+ Sets the SoftLayer account user name. If not specified, it is assumed SL_API_USERNAME environment variable is set.
89
+
90
+ --sl_api_key SL_API_KEY, -k SL_API_KEY:
91
+ Sets the SoftLayer API key. If not specified, it is assumed SL_API_KEY environment variable is set.
92
+
93
+ --sl_endpoint_url SL_API_BASE_URL, -e SL_API_BASE_URL:
94
+ Sets the SoftLayer endpoint URL. If not specified, it assumed SL_API_BASE_URL environment variable is set to API_PUBLIC_ENDPOINT or API_PRIVATE_ENDPOINT.
95
+ Defaults to API_PUBLIC_ENDPOINT.
96
+
97
+ --output_dir OUTPUTDIR, -o OUTPUTDIR:
98
+ Sets the root directory to create box output under.
99
+
100
+ --only_templates, -t:
101
+ Only create boxes for the CCI templates and not compute or flex images.
102
+
103
+ --only_images, -i:
104
+ Only create boxes for the compute or flex images and not the CCI templates.
105
+
106
+ --only_public_images, -g:
107
+ Only create boxes for the public compute or flex images and not the CCI templates.
108
+
109
+ --only_private_images, -p:
110
+ Only create boxes for the private compute or flex images and not the CCI templates.
111
+
112
+ --default_domain:
113
+ Set default vm domain.
114
+
115
+ --default_datacenter:
116
+ Set default vm datacenter.
117
+
118
+ --default_monthly_billing:
119
+ Set default billing type to monthly.
120
+
121
+ --default_vlan_private:
122
+ Set default vm private vlan.
123
+
124
+ --default_vlan_public:
125
+ Set default vm public vlan.
126
+
127
+ FILTER
128
+ String used to filter template and compute/flex images by name to export boxes for specific matches. Supports filtering by regular expression.
129
+
130
+ EOF
131
+
132
+ exit 0
133
+
134
+ when '--sl_username'
135
+ $sl[:sl_credentials][:username] = optval.to_s
136
+
137
+ when '--sl_api_key'
138
+ $sl[:sl_credentials][:api_key] = optval.to_s
139
+
140
+ when '--sl_endpoint_url'
141
+ if ! [ "API_PUBLIC_ENDPOINT", "API_PRIVATE_ENDPOINT" ].include?(optval.to_s.upcase)
142
+ $stderr.puts "ERROR: Invalid endpoint_url value: " + optval.to_s.upcase
143
+ exit 2
144
+ end
145
+
146
+ $sl[:sl_credentials][:endpoint_url] = (optval.to_s.upcase == 'API_PUBLIC_ENDPOINT' ? SoftLayer::API_PUBLIC_ENDPOINT : SoftLayer::API_PRIVATE_ENDPOINT )
147
+
148
+ when '--output_dir'
149
+ if File.exists?(optval.to_s) && File.ftype(optval.to_s) != 'directory'
150
+ $stderr.puts "ERROR: Path is not a directory: " + optval.to_s
151
+ exit 2
152
+ end
153
+
154
+ $boxes[:dir][:output_root] = File.expand_path(optval.to_s)
155
+ $boxes[:dir][:vagrantfiles_root] = File.join($boxes[:dir][:output_root], $boxes[:dir][:vagrantfiles])
156
+ $boxes[:dir][:boxes_root] = File.join($boxes[:dir][:output_root], $boxes[:dir][:boxes])
157
+
158
+ if File.exists?($boxes[:dir][:vagrantfiles_root]) && File.ftype($boxes[:dir][:vagrantfiles_root]) != 'directory'
159
+ $stderr.puts "ERROR: Output directory subdir is not a directory: " + $boxes[:dir][:vagrantfiles_root]
160
+ exit 2
161
+ end
162
+
163
+ if File.exists?($boxes[:dir][:boxes_root]) && File.ftype($boxes[:dir][:boxes_root]) != 'directory'
164
+ $stderr.puts "ERROR: Output directory subdir is not a directory: " + $boxes[:dir][:boxes_root]
165
+ exit 2
166
+ end
167
+
168
+ when '--only_templates'
169
+ $boxes[:images][:public] = false
170
+ $boxes[:images][:private] = false
171
+
172
+ when '--only_images'
173
+ $boxes[:templates] = false
174
+
175
+ when '--only_public_images'
176
+ $boxes[:templates] = false
177
+ $boxes[:images][:private] = false
178
+
179
+ when '--only_private_images'
180
+ $boxes[:templates] = false
181
+ $boxes[:images][:public] = false
182
+
183
+ when '--default_domain'
184
+ $boxes[:domain] = optval.to_s
185
+
186
+ when '--default_datacenter'
187
+ $boxes[:datacenter] = optval.to_s
188
+
189
+ when '--default_monthly_billing'
190
+ $boxes[:monthly_billing] = true
191
+
192
+ when '--default_vlan_private'
193
+ $boxes[:vlan_private] = optval.to_s
194
+
195
+ when'--default_vlan_public'
196
+ $boxes[:vlan_public] = optval.to_s
197
+
198
+ end
199
+ end
200
+
201
+ $boxes[:dir][:vagrantfiles_root] = File.join($boxes[:dir][:output_root], $boxes[:dir][:vagrantfiles])
202
+ $boxes[:dir][:boxes_root] = File.join($boxes[:dir][:output_root], $boxes[:dir][:boxes])
203
+ $boxes[:metadata_path] = File.join($boxes[:dir][:output_root], "metadata.json")
204
+
205
+ begin
206
+ [ $boxes[:dir][:output_root], $boxes[:dir][:vagrantfiles_root], $boxes[:dir][:boxes_root] ].each do |path|
207
+ Dir.mkdir(path, 0755) if ! File.exists?(path)
208
+ end
209
+ rescue Exception => e
210
+ $stderr.puts "ERROR: Failed to create output directories: " + e.message
211
+ exit 1
212
+ end
213
+
214
+ $sl[:sl_credentials][:username] = ENV["SL_API_USERNAME"] if $sl[:sl_credentials][:username].nil? && ENV.include?("SL_API_USERNAME")
215
+ $sl[:sl_credentials][:api_key] = ENV["SL_API_KEY"] if $sl[:sl_credentials][:api_key].nil? && ENV.include?("SL_API_KEY")
216
+ $sl[:sl_credentials][:endpoint_url] = (ENV["SL_API_BASE_URL"] == "API_PUBLIC_ENDPOINT" ? SoftLayer::API_PUBLIC_ENDPOINT : SoftLayer::API_PRIVATE_ENDPOINT ) if $sl[:sl_credentials][:endpoint_url].nil? && ENV.include?("SL_API_BASE_URL")
217
+
218
+ if $sl[:sl_credentials][:username].nil?
219
+ $stderr.puts "ERROR: No SoftLayer username specified"
220
+ exit 2
221
+ end
222
+
223
+ if $sl[:sl_credentials][:username].nil?
224
+ $stderr.puts "ERROR: No SoftLayer user name specified"
225
+ exit 2
226
+ end
227
+
228
+ if $sl[:sl_credentials][:api_key].nil?
229
+ $stderr.puts "ERROR: No SoftLayer API key specified"
230
+ exit 2
231
+ end
232
+ end
233
+
234
+ def procCliArgs()
235
+ if ARGV.length > 2
236
+ $stderr.puts "ERROR: Invalid argument supplied, please check help"
237
+ exit 2
238
+ elsif ARGV.length == 1
239
+ begin
240
+ $boxes[:filter] = Regexp.new(ARGV[0], Regexp::IGNORECASE)
241
+ rescue Exception => e
242
+ $stderr.puts "ERROR: Filter value is not a valid regular expression: " + e.message
243
+ exit 2
244
+ end
245
+ end
246
+ end
247
+
248
+ def getBoxData()
249
+ begin
250
+ $sl[:service][:virtual_guest] = SoftLayer::Service.new("SoftLayer_Virtual_Guest", $sl[:sl_credentials]) if $boxes[:templates]
251
+ $sl[:service][:account] = SoftLayer::Service.new("SoftLayer_Account", $sl[:sl_credentials]) if $boxes[:images][:private]
252
+ $sl[:service][:virtual_guest_block_device_template_group] = SoftLayer::Service.new("SoftLayer_Virtual_Guest_Block_Device_Template_Group", $sl[:sl_credentials]) if $boxes[:images][:public]
253
+ rescue Exception => e
254
+ $stderr.puts "ERROR: Failed to create SoftLayer service object: " + e.message
255
+ exit 1
256
+ end
257
+
258
+ begin
259
+ $sl[:data][:create_opts] = $sl[:service][:virtual_guest].getCreateObjectOptions if $boxes[:templates]
260
+ $sl[:data][:private_images] = $sl[:service][:account].getBlockDeviceTemplateGroups.delete_if { |block_device| ! block_device.has_key?("globalIdentifier") } if $boxes[:images][:private]
261
+ $sl[:data][:public_images] = $sl[:service][:virtual_guest_block_device_template_group].getPublicImages.delete_if { |block_device| ! block_device.has_key?("globalIdentifier") } if $boxes[:images][:public]
262
+ rescue Exception => e
263
+ $stderr.puts "ERROR: Failed to retrieve SoftLayer service data: " + e.message
264
+ exit 1
265
+ end
266
+
267
+ if $boxes[:templates]
268
+ $sl[:data][:create_opts]["operatingSystems"].each do |os|
269
+ boxgroup = os["template"]["operatingSystemReferenceCode"].strip.gsub(/[()]/,'').gsub(/[^a-zA-Z0-9_.-]/, '_').upcase
270
+
271
+ #We dont want to allow separate instances for templates of same group name since the only difference is additional descriptions
272
+ if ! $boxes[:data].has_key?(boxgroup)
273
+ $boxes[:data][boxgroup] = Array.new()
274
+
275
+ $boxes[:data][boxgroup].push(
276
+ {
277
+ :type => :template,
278
+ :name => os["template"]["operatingSystemReferenceCode"],
279
+ :description => [ os["itemPrice"]["item"]["description"] ]
280
+ }
281
+ )
282
+ else
283
+ $boxes[:data][boxgroup][0][:description].push(os["itemPrice"]["item"]["description"])
284
+ end
285
+ end
286
+ end
287
+
288
+ $boxes[:images].each_key do |image_view|
289
+ if $boxes[:images][image_view]
290
+ $sl[:data][(image_view == :public ? :public_images : :private_images)].each do |image|
291
+ boxgroup = image["name"].strip.gsub(/[()]/,'').gsub(/[^a-zA-Z0-9_.-]/, '_').upcase
292
+
293
+ $boxes[:data][boxgroup] = Array.new() if ! $boxes[:data].has_key?(boxgroup)
294
+ $boxes[:data][boxgroup].push(
295
+ {
296
+ :type => :block_image,
297
+ :name => image["name"],
298
+ :global_id => image["globalIdentifier"],
299
+ :note => image["note"].to_s,
300
+ :summary => image["summary"].to_s,
301
+ :visibility => image_view
302
+ }
303
+ )
304
+ end
305
+ end
306
+ end
307
+ end
308
+
309
+ def filterBoxes()
310
+ if ! $boxes[:filter].nil?
311
+ $boxes[:data].each_key do |boxgroup|
312
+ begin
313
+ $boxes[:data][boxgroup].delete_if { |box| ! box[:name].match($boxes[:filter]) }
314
+ rescue Exception => e
315
+ $stderr.puts "ERROR: Failed to filter Softlayer boxes: " + e.message
316
+ exit 1
317
+ end
318
+ end
319
+ end
320
+ end
321
+
322
+ def saveBoxFiles()
323
+ begin
324
+ File.open($boxes[:metadata_path], "w", 0644) { |fout| fout.puts $boxes[:file_templates][:metadata_json] }
325
+ rescue Exception => e
326
+ $stderr.puts "ERROR: Failed to save box metadata JSON data: " + e.message
327
+ exit 1
328
+ end
329
+
330
+ $boxes[:data].each_key do |boxgroup|
331
+ $boxes[:data][boxgroup].each do |box|
332
+ boxFileName = ($boxes[:data][boxgroup].length > 1 ? boxgroup + "_" + ($boxes[:data][boxgroup].index(box) + 1).to_s : boxgroup)
333
+
334
+ begin
335
+ File.open(File.join($boxes[:dir][:vagrantfiles_root], boxFileName + ".vagrantfile"), "w", 0644) do |fout|
336
+ fout.puts $boxes[:file_templates][:created_by]
337
+ fout.puts
338
+
339
+ fout.puts $boxes[:file_templates][:os_templates_avail] if box[:type] == :template
340
+ fout.puts box[:description].map { |descr| "# " + descr }.join("\n") if box[:type] == :template
341
+
342
+ fout.puts $boxes[:file_templates][:image_detail] if box[:type] == :block_image
343
+ fout.puts "# Global Identifier: " + box[:global_id].to_s if box[:type] == :block_image
344
+ fout.puts "# Name: " + box[:name] if box[:type] == :block_image
345
+ fout.puts "# Summary: " + box[:summary].to_s if box[:type] == :block_image
346
+ fout.puts "# Note: " + box[:note].to_s if box[:type] == :block_image
347
+ fout.puts "# Visibility: " + (box[:visibility] == :public ? "public" : "private" ) if box[:type] == :block_image
348
+
349
+ fout.puts
350
+ fout.puts $boxes[:file_templates][:vagrant_config_start]
351
+ fout.puts $boxes[:file_templates][:indent][4] + $boxes[:file_templates][:sl_config_start]
352
+
353
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.datacenter = \"" + $boxes[:datacenter] + "\"" if $boxes[:datacenter]
354
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.domain = \"" + $boxes[:domain] + "\"" if $boxes[:domain]
355
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.hourly_billing = false" if $boxes[:monthly_billing]
356
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.operating_system = \"" + box[:name] + "\"" if box[:type] == :template
357
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.image_guid = \"" + box[:global_id].to_s + "\"" if box[:type] == :block_image
358
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.vlan_private = \"" + $boxes[:vlan_private] + "\"" if $boxes[:vlan_private]
359
+ fout.puts $boxes[:file_templates][:indent][8] + "sl.vlan_public = \"" + $boxes[:vlan_public] + "\"" if $boxes[:vlan_public]
360
+
361
+ fout.puts $boxes[:file_templates][:indent][4] + $boxes[:file_templates][:end]
362
+ fout.puts $boxes[:file_templates][:end]
363
+ end
364
+ rescue Exception => e
365
+ $stderr.puts "ERROR: Failed to save box Vagrantfile: " + e.message
366
+ exit 1
367
+ end
368
+ end
369
+ end
370
+ end
371
+
372
+ def createBoxes()
373
+ $boxes[:data].each_key do |boxgroup|
374
+ $boxes[:data][boxgroup].each do |box|
375
+ boxFileName = ($boxes[:data][boxgroup].length > 1 ? boxgroup + "_" + ($boxes[:data][boxgroup].index(box) + 1).to_s : boxgroup)
376
+
377
+ begin
378
+ Dir.mktmpdir do |tmpDir|
379
+ FileUtils.cd(tmpDir) do
380
+ FileUtils.cp($boxes[:metadata_path], File.join(tmpDir,"metadata.json"), :preserve => true)
381
+ FileUtils.cp(File.join($boxes[:dir][:vagrantfiles_root], boxFileName + ".vagrantfile"), File.join(tmpDir, "Vagrantfile"), :preserve => true)
382
+
383
+ result = %x(tar -czvf "#{File.join($boxes[:dir][:boxes_root], boxFileName + ".box.tar.gz")}" Vagrantfile metadata.json)
384
+
385
+ raise result if $?.exitstatus != 0
386
+
387
+ FileUtils.mv(File.join($boxes[:dir][:boxes_root], boxFileName + ".box.tar.gz"), File.join($boxes[:dir][:boxes_root], boxFileName + ".box"), :force => true)
388
+ FileUtils.chmod(0644, File.join($boxes[:dir][:boxes_root], boxFileName + ".box"))
389
+ end
390
+ end
391
+ rescue Exception => e
392
+ $stderr.puts "ERROR: Failed to save Vagrant box: " + e.message
393
+ exit 1
394
+ end
395
+ end
396
+ end
397
+ end
398
+
399
+ def main()
400
+ procCliOptions()
401
+ procCliArgs()
402
+ getBoxData()
403
+ filterBoxes()
404
+ saveBoxFiles()
405
+ createBoxes()
406
+ end
407
+
408
+ main
@@ -1,54 +1,58 @@
1
- module VagrantPlugins
2
- module SoftLayer
3
- module Action
4
- # This creates a new instance.
5
- class CreateInstance
6
- include Util::Network
7
- include Util::Warden
8
-
9
- def initialize(app, env)
10
- @app = app
11
- end
12
-
13
- def call(env)
14
- @env = env
15
-
16
- @env[:ui].info I18n.t("vagrant_softlayer.vm.creating")
17
-
18
- result = sl_warden { env[:sl_connection].createObject(order_template) }
19
- @env[:machine].id = result["id"].to_s
20
-
21
- @app.call(@env)
22
- end
23
-
24
- def get_hostname
25
- @env[:machine].provider_config.hostname || @env[:machine].config.vm.hostname
26
- end
27
-
28
- def order_template
29
- template = {
30
- "dedicatedAccountHostOnlyFlag" => @env[:machine].provider_config.dedicated,
31
- "domain" => @env[:machine].provider_config.domain,
32
- "hostname" => get_hostname,
33
- "hourlyBillingFlag" => @env[:machine].provider_config.hourly_billing,
34
- "localDiskFlag" => @env[:machine].provider_config.local_disk,
35
- "maxMemory" => @env[:machine].provider_config.max_memory,
36
- "networkComponents" => [ { :maxSpeed => @env[:machine].provider_config.network_speed } ],
37
- "operatingSystemReferenceCode" => @env[:machine].provider_config.operating_system,
38
- "privateNetworkOnlyFlag" => @env[:machine].provider_config.private_only,
39
- "sshKeys" => ssh_keys(@env),
40
- "startCpus" => @env[:machine].provider_config.start_cpus
41
- }
42
-
43
- template["datacenter"] = { :name => @env[:machine].provider_config.datacenter } if @env[:machine].provider_config.datacenter
44
- template["postInstallScriptUri"] = @env[:machine].provider_config.post_install if @env[:machine].provider_config.post_install
45
- template["primaryNetworkComponent"] = { :networkVlan => { :id => @env[:machine].provider_config.vlan_public } } if @env[:machine].provider_config.vlan_public
46
- template["primaryBackendNetworkComponent"] = { :networkVlan => { :id => @env[:machine].provider_config.vlan_private } } if @env[:machine].provider_config.vlan_private
47
- template["userData"] = [ { :value => @env[:machine].provider_config.user_data } ] if @env[:machine].provider_config.user_data
48
-
49
- return template
50
- end
51
- end
52
- end
53
- end
54
- end
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Action
4
+ # This creates a new instance.
5
+ class CreateInstance
6
+ include Util::Network
7
+ include Util::Warden
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ @env = env
15
+
16
+ @env[:ui].info I18n.t("vagrant_softlayer.vm.creating")
17
+
18
+ sl_warden { env[:sl_product_order].verifyOrder(env[:sl_virtual_guest].generateOrderTemplate(order_template)) }
19
+
20
+ result = sl_warden { env[:sl_virtual_guest].createObject(order_template) }
21
+ @env[:machine].id = result["id"].to_s
22
+
23
+ @app.call(@env)
24
+ end
25
+
26
+ def get_hostname
27
+ @env[:machine].provider_config.hostname || @env[:machine].config.vm.hostname
28
+ end
29
+
30
+ def order_template
31
+ template = {
32
+ "dedicatedAccountHostOnlyFlag" => @env[:machine].provider_config.dedicated,
33
+ "domain" => @env[:machine].provider_config.domain,
34
+ "hostname" => get_hostname,
35
+ "hourlyBillingFlag" => @env[:machine].provider_config.hourly_billing,
36
+ "localDiskFlag" => @env[:machine].provider_config.local_disk,
37
+ "maxMemory" => @env[:machine].provider_config.max_memory,
38
+ "networkComponents" => [ { :maxSpeed => @env[:machine].provider_config.network_speed } ],
39
+ "privateNetworkOnlyFlag" => @env[:machine].provider_config.private_only,
40
+ "sshKeys" => ssh_keys(@env),
41
+ "startCpus" => @env[:machine].provider_config.start_cpus
42
+ }
43
+
44
+ template["blockDevices"] = @env[:machine].provider_config.disk_capacity.map{ |key,value| { "device"=> key.to_s, "diskImage" => { "capacity" => value.to_s } } } if @env[:machine].provider_config.disk_capacity
45
+ template["datacenter"] = { :name => @env[:machine].provider_config.datacenter } if @env[:machine].provider_config.datacenter
46
+ template["blockDeviceTemplateGroup"] = { :globalIdentifier => @env[:machine].provider_config.image_guid } if @env[:machine].provider_config.image_guid
47
+ template["operatingSystemReferenceCode"] = @env[:machine].provider_config.operating_system if !@env[:machine].provider_config.image_guid
48
+ template["postInstallScriptUri"] = @env[:machine].provider_config.post_install if @env[:machine].provider_config.post_install
49
+ template["primaryNetworkComponent"] = { :networkVlan => { :id => @env[:machine].provider_config.vlan_public } } if @env[:machine].provider_config.vlan_public
50
+ template["primaryBackendNetworkComponent"] = { :networkVlan => { :id => @env[:machine].provider_config.vlan_private } } if @env[:machine].provider_config.vlan_private
51
+ template["userData"] = [ { :value => @env[:machine].provider_config.user_data } ] if @env[:machine].provider_config.user_data
52
+
53
+ return template
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end