vagrant_filoo 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +61 -0
  3. data/Gemfile +14 -0
  4. data/LICENSE +22 -0
  5. data/README.md +207 -0
  6. data/Rakefile +5 -0
  7. data/doc/img_res/filoo_logo.png +0 -0
  8. data/doc/img_res/filoo_wolke.png +0 -0
  9. data/example_box/README.md +13 -0
  10. data/example_box/metadata.json +3 -0
  11. data/filoo.box +0 -0
  12. data/lib/vagrant_filoo/action/create_server.rb +51 -0
  13. data/lib/vagrant_filoo/action/get_images.rb +21 -0
  14. data/lib/vagrant_filoo/action/is_created.rb +22 -0
  15. data/lib/vagrant_filoo/action/is_stopped.rb +18 -0
  16. data/lib/vagrant_filoo/action/message_already_created.rb +16 -0
  17. data/lib/vagrant_filoo/action/message_not_created.rb +16 -0
  18. data/lib/vagrant_filoo/action/read_ssh_info.rb +40 -0
  19. data/lib/vagrant_filoo/action/read_state.rb +65 -0
  20. data/lib/vagrant_filoo/action/start_instance.rb +48 -0
  21. data/lib/vagrant_filoo/action/stop_instance.rb +31 -0
  22. data/lib/vagrant_filoo/action/terminate_instance.rb +24 -0
  23. data/lib/vagrant_filoo/action/test.rb +2 -0
  24. data/lib/vagrant_filoo/action.rb +184 -0
  25. data/lib/vagrant_filoo/cloud_compute.rb +629 -0
  26. data/lib/vagrant_filoo/config.rb +54 -0
  27. data/lib/vagrant_filoo/errors.rb +81 -0
  28. data/lib/vagrant_filoo/plugin.rb +73 -0
  29. data/lib/vagrant_filoo/provider.rb +52 -0
  30. data/lib/vagrant_filoo/util/timer.rb +17 -0
  31. data/lib/vagrant_filoo/version.rb +5 -0
  32. data/lib/vagrant_filoo.rb +17 -0
  33. data/locales/en.yml +122 -0
  34. data/sample_config/Vagrantfile_example +23 -0
  35. data/spec/spec_helper.rb +0 -0
  36. data/spec/vagrant_filoo/config_spec.rb +70 -0
  37. data/templates/metadata.json.erb +3 -0
  38. data/templates/vagrant-filoo_package_Vagrantfile.erb +5 -0
  39. data/vagrant_filoo.gemspec +58 -0
  40. metadata +178 -0
@@ -0,0 +1,629 @@
1
+ require 'rest-client'
2
+ require_relative 'errors'
3
+ require 'json'
4
+
5
+ module VagrantPlugins
6
+ module Filoo
7
+ module CloudCompute
8
+ LOGGER = Log4r::Logger.new('vagrant_filoo::cloud_compute')
9
+
10
+ ################################
11
+ # Application specific methods #
12
+ ################################
13
+ CREATE_SERVER_RESOURCE = '/vserver/create'
14
+ DELETE_SERVER_RESOURCE = '/vserver/delete'
15
+ LIST_SERVER_RESOURCE ='/vserver/list'
16
+ SERVERSTATUS_RESOURCE = '/vserver/status'
17
+ START_RESOURCE = '/vserver/start'
18
+ STOP_RESOURCE = '/vserver/stop'
19
+ LIST_NIC_RESOURCE = '/vserver/list_nic'
20
+ ADD_NIC_RESOURCE = '/vserver/add_nic'
21
+ DELETE_NIC_RESOURCE = '/vserver/del_nic'
22
+
23
+ ########################################
24
+ # Virtual Server Creation and checking #
25
+ ########################################
26
+
27
+ CREATE_SERVER_TIMEOUT = 30
28
+ VALID_TYPES = ['dynamic','fixed']
29
+ VALID_CPU_COUNTS = [1, 2, 3, 4, 5, 6, 7, 8]
30
+ VALID_RAM = [128, 256, 512, 1024, 2048, 3072, 4096, 5120, 6144, 7186, 8192]
31
+
32
+ #####################################################################
33
+ # create a virtual server with the given parameters
34
+ # parameters {hash} with following fields
35
+ # -type=(dynamic|fixed) : dynmaic (minutely) or vServer (monthly)
36
+ # -cpu=(1-8): Anzahl vCPUs
37
+ # -ram=(128,256,512,1024,2048,3072,4096,5120,6144,7186,8192): Ram in MB
38
+ # -hdd=(10-2000): HDDp Space in GB, 10GB-Steps (10,20,30,...)
39
+ # -cd_imageid ID. Only for images with autoinstall=1.
40
+ ####################################################################
41
+
42
+ def self.createServer(params, baseUrl, apiKey)
43
+ checkServerParams(params)
44
+ createServerUrl = baseUrl + CREATE_SERVER_RESOURCE
45
+ jobId = call4JobId createServerUrl, apiKey, params
46
+ vmid = nil;
47
+ jobResult = nil
48
+
49
+ begin
50
+ jobResult = waitJobDone(jobId, baseUrl, apiKey, CREATE_SERVER_TIMEOUT)
51
+ vmid = jobResult[:result]['vmid']
52
+
53
+ if jobResult[:result]['vmid'].nil?
54
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
55
+ code: 500,
56
+ message: "Unexpected return value to Api Call POST " + createServerUrl + " #{params} " + {:jobid => jobId}.to_json,
57
+ description: "Response has no field vmid in result. Response: " + jobResult.to_json
58
+ end
59
+
60
+ rescue VagrantPlugins::Filoo::Errors::FilooJobResultTimeoutError => e
61
+ raise VagrantPlugins::Filoo::Errors::CreateInstanceTimeout,
62
+ job_id: jobId,
63
+ timeout: e.timeout
64
+ rescue VagrantPlugins::Filoo::Errors::FilooJobFailedError => e
65
+ vmid = jobResult[:result]['vmid']
66
+ end
67
+
68
+ serverStatus = nil;
69
+ checkParams = {:type => params[:type],
70
+ :cpu => params[:cpu],
71
+ :ram => params[:ram],
72
+ :hdd => params[:hdd]}
73
+
74
+ begin
75
+ serverStatus = self.checkServerStatus(vmid, checkParams, baseUrl, apiKey)
76
+ rescue VagrantPlugins::Filoo::Errors::FilooApiError => e
77
+
78
+ if e.code == 403
79
+ raise VagrantPlugins::Filoo::Errors::UnexpectedStateError,
80
+ resource: LIST_SERVER_RESOURCE,
81
+ jobid: jobResult[:jobid],
82
+ job_command: jobResult[:job_command],
83
+ state: serverList,
84
+ message: "Unexpected State of server list " + serverList.to_json,
85
+ description: "Server with vmid #{vmid} should have been created "
86
+ + "(see #{baseUrl}#{LIST_SERVER_RESOURCE} action : list) "
87
+ + "Server is not created though system gave feedback with status #{jobResult[:status]} "
88
+ + "to task #{jobResult[:job_command]} #{jobResult[:job_param]} with jobid #{jobResult[:jobid]}"
89
+ end
90
+
91
+ raise e
92
+ end
93
+
94
+ serverStatus
95
+ end
96
+
97
+ def self.checkServerParams params
98
+
99
+ if !params.is_a?(Hash)
100
+ raise VagrantPlugins::Filoo::Errors::ConfigError,
101
+ message: "Invalid type of parameter params, must be Hash but is #{params.class}"
102
+ end
103
+
104
+ if params[:type].nil? or ! ['dynamic','fixed'].include? params[:type]
105
+ raise VagrantPlugins::Filoo::Errors::ConfigError,
106
+ message: "Invalid value #{params[:type]} for configuration field type, must be one of the following numbers #{VALID_TYPES}"
107
+ end
108
+
109
+ if params[:cpu].nil? or ! VALID_CPU_COUNTS.include? params[:cpu]
110
+ raise VagrantPlugins::Filoo::Errors::ConfigError,
111
+ message: "Invalid value #{params[:cpu]} for configuration field cpu, must be one of the following numbers #{VALID_CPU_COUNTS}"
112
+ end
113
+
114
+ if params[:ram].nil? or ! VALID_RAM.include? params[:ram]
115
+ raise VagrantPlugins::Filoo::Errors::ConfigError,
116
+ message: "Invalid value #{params[:ram]} for configuration field ram, must be one of the following numbers #{VALID_RAM.to_json}"
117
+ end
118
+
119
+ if params[:hdd].nil? or params[:hdd] < 10 or params[:hdd] > 2000 or params[:hdd] % 10 != 0
120
+ raise VagrantPlugins::Filoo::Errors::ConfigError,
121
+ message: "Invalid value #{params[:hd]} for configuration field hd, must be a number between 10-2000 "
122
+ + " with steps of 10,20,30..."
123
+ end
124
+
125
+ end
126
+
127
+ # Server removal
128
+ DELETE_SERVER_TIMEOUT = 30
129
+
130
+ def self.deleteServer(vmid, baseUrl, apiKey)
131
+ deleteServereUrl = baseUrl + DELETE_SERVER_RESOURCE
132
+ jobId = call4JobId deleteServereUrl, apiKey, {:vmid => vmid}
133
+ jobResult = nil;
134
+
135
+ begin
136
+ jobResult = waitJobDone(jobId, baseUrl, apiKey, DELETE_SERVER_TIMEOUT)
137
+ rescue VagrantPlugins::Filoo::Errors::FilooJobResultTimeoutError => e
138
+ raise VagrantPlugins::Filoo::Errors::DeleteInstanceTimeout,
139
+ job_id: jobId,
140
+ timeout: e.timeout
141
+ end
142
+
143
+ serverList = self.getServers(baseUrl + LIST_SERVER_RESOURCE, apiKey)
144
+
145
+ if !serverList["#{vmid}"].nil?
146
+ raise VagrantPlugins::Filoo::Errors::UnexpectedStateError,
147
+ resource: LIST_SERVER_RESOURCE,
148
+ jobid: jobResult[:jobid],
149
+ job_command: jobResult[:job_command],
150
+ state: serverList,
151
+ message: "Unexpected State of server list " + serverList.to_json,
152
+ description: "Server with vmid #{vmid} should have been deleted from server list but is not "
153
+ + "(see #{baseUrl}#{LIST_SERVER_RESOURCE} action : list) "
154
+ + "though system gave feedback with status #{jobResult[:status]} to task "
155
+ + "#{jobResult[:job_command]} #{jobResult[:job_param]} with jobid #{jobResult[:jobid]}"
156
+ end
157
+
158
+ return serverList
159
+ end
160
+
161
+ # start server
162
+
163
+ START_INSTANCE_TIMEOUT = 60
164
+
165
+ def self.startInstance(vmid, baseUrl, apiKey, filooConfig)
166
+
167
+ shouldNotChangeParams = {
168
+ :type => filooConfig.type,
169
+ :cpu => filooConfig.cpu,
170
+ :ram => filooConfig.ram,
171
+ :hdd => filooConfig.hdd
172
+ }
173
+
174
+ begin
175
+ compareServerStatus(vmid, shouldNotChangeParams, baseUrl, apiKey)
176
+ rescue VagrantPlugins::Filoo::Errors::InvaildServerParameterError => e
177
+ paramKey = "#{e.paramName}"
178
+ raise VagrantPlugins::Filoo::Errors::ConfigError,
179
+ message: "Can not update filoo provider parameter '#{e.paramName}'. Parameter 'filoo.#{e.paramName}' must be set to #{e.serverStatus[paramKey]}.
180
+ Please create new instance if you need updated this parameters."
181
+ end
182
+
183
+ nicList = self.listNic(vmid, baseUrl, apiKey)
184
+
185
+ if filooConfig.additional_nic && nicList.count < 1
186
+ self.addNic(vmid, baseUrl, apiKey)
187
+ elsif !filooConfig.additional_nic && nicList.count > 0
188
+ self.deleteNic(vmid, baseUrl, apiKey)
189
+ end
190
+
191
+ url = "#{baseUrl}#{START_RESOURCE}"
192
+ jobId = call4JobId url, apiKey, {:vmid => vmid}
193
+ jobResult = nil;
194
+
195
+ begin
196
+ jobResult = waitJobDone(jobId, baseUrl, apiKey, START_INSTANCE_TIMEOUT)
197
+ rescue VagrantPlugins::Filoo::Errors::FilooJobResultTimeoutError => e
198
+ raise VagrantPlugins::Filoo::Errors::StartInstanceTimeout,
199
+ job_id: jobId,
200
+ timeout: e.timeout
201
+ end
202
+
203
+ serverStatus = nil;
204
+
205
+ begin
206
+ serverStatus = checkServerStatus(vmid, {:vmid => vmid, :vmstatus => "running"}, baseUrl, apiKey)
207
+
208
+ rescue VagrantPlugins::Filoo::Errors::FilooApiError => e
209
+ if e.code == 403
210
+ raise VagrantPlugins::Filoo::Errors::UnexpectedStateError,
211
+ resource: LIST_SERVER_RESOURCE,
212
+ jobid: jobResult[:jobid],
213
+ job_command: jobResult[:job_command],
214
+ state: serverList,
215
+ message: "Unexpected State of server list " + serverList.to_json,
216
+ description: "Server with vmid #{vmid} should be in list "
217
+ + "(see #{baseUrl}#{LIST_SERVER_RESOURCE} action : list) "
218
+ + "Server is not in list though system gave feedback with status #{jobResult[:status]} "
219
+ + "to task #{jobResult[:job_command]} #{jobResult[:job_param]} with jobid #{jobResult[:jobid]}"
220
+ end
221
+ raise e
222
+ end
223
+
224
+ return serverStatus
225
+ end
226
+
227
+ # stop instance
228
+
229
+ STOP_INSTANCE_TIMEOUT = 60
230
+
231
+ def self.stopInstance(vmid, baseUrl, apiKey)
232
+ stopInstanceUrl = baseUrl + STOP_RESOURCE
233
+ jobId = call4JobId(stopInstanceUrl, apiKey, {:vmid => vmid})
234
+ jobResult = nil
235
+
236
+ begin
237
+ jobResult = waitJobDone(jobId, baseUrl, apiKey, STOP_INSTANCE_TIMEOUT)
238
+ rescue VagrantPlugins::Filoo::Errors::FilooJobResultTimeoutError => e
239
+ raise VagrantPlugins::Filoo::Errors::StopInstanceTimeout,
240
+ job_id: jobId,
241
+ timeout: e.timeout
242
+ end
243
+
244
+ serverStatus = nil;
245
+
246
+ begin
247
+ serverStatus = checkServerStatus(vmid, {:vmid => vmid, :vmstatus => "stopped"}, baseUrl, apiKey)
248
+ rescue VagrantPlugins::Filoo::Errors::FilooApiError => e
249
+ if e.code == 403
250
+ raise VagrantPlugins::Filoo::Errors::UnexpectedStateError,
251
+ resource: LIST_SERVER_RESOURCE,
252
+ jobid: jobResult[:jobid],
253
+ job_command: jobResult[:job_command],
254
+ state: serverList,
255
+ message: "Unexpected State of server list " + serverList.to_json,
256
+ description: "Server with vmid #{vmid} should be in list "
257
+ + "(see #{baseUrl}#{LIST_SERVER_RESOURCE} action : list) "
258
+ + "Server is not in list though system gave feedback with status #{jobResult[:status]} "
259
+ + "to task #{jobResult[:job_command]} #{jobResult[:job_param]} with jobid #{jobResult[:jobid]}"
260
+ end
261
+ raise e
262
+ end
263
+
264
+ end
265
+
266
+
267
+ # list servers
268
+
269
+ def self.getServers(baseUrl, apiKey)
270
+ begin
271
+ serverList = self.call(baseUrl + LIST_SERVER_RESOURCE,apiKey, {:detailed => false})['return']
272
+ hashFromServerList(serverList)
273
+ rescue ArgumentError => e
274
+ raise ConfigError, e.message
275
+ end
276
+ end
277
+
278
+ def self.hashFromServerList serverList
279
+ serversHash = {}
280
+ serverList.each { |serverInfo|
281
+ serversHash[serverInfo['vmid']] = serverInfo
282
+ serversHash[serverInfo['vmid']].delete('vmid')
283
+ }
284
+ return serversHash
285
+ end
286
+
287
+ def self.hashFromServerList serverList
288
+ serversHash = {}
289
+ serverList.each { |serverInfo|
290
+ serversHash[serverInfo['vmid']] = serverInfo
291
+ serversHash[serverInfo['vmid']].delete('vmid')
292
+ }
293
+ return serversHash
294
+ end
295
+
296
+ # list nic
297
+
298
+ def self.listNic(vmid, baseUrl, apiKey)
299
+ begin
300
+ return self.call(baseUrl + LIST_NIC_RESOURCE, apiKey, {:vmid => vmid})['return']
301
+ rescue ArgumentError => e
302
+ raise VagrantPlugins::Filoo::Errors::ConfigError, message: e.message
303
+ end
304
+ end
305
+
306
+ # add nic
307
+
308
+ def self.addNic(vmid, baseUrl, apiKey)
309
+
310
+ begin
311
+ return self.call(baseUrl + ADD_NIC_RESOURCE, apiKey, {:vmid => vmid})['return']
312
+ rescue ArgumentError => e
313
+ raise VagrantPlugins::Filoo::Errors::ConfigError, message: e.message
314
+ end
315
+
316
+ end
317
+
318
+ # add nic
319
+
320
+ def self.deleteNic(vmid, baseUrl, apiKey)
321
+
322
+ begin
323
+ return self.call(baseUrl + DELETE_NIC_RESOURCE, apiKey, {:vmid => vmid})['return']
324
+ rescue ArgumentError => e
325
+ raise VagrantPlugins::Filoo::Errors::ConfigError, message: e.message
326
+ end
327
+
328
+ end
329
+
330
+ # server status
331
+
332
+ def self.getServerStatus(vmid, baseUrl, apiKey)
333
+
334
+ if vmid.nil?
335
+ return :not_created
336
+ end
337
+
338
+ begin
339
+ return self.call(baseUrl + SERVERSTATUS_RESOURCE, apiKey, {:vmid => vmid, :detailed => true})['return']
340
+ rescue ArgumentError => e
341
+ raise VagrantPlugins::Filoo::Errors::ConfigError, message: e.message
342
+ end
343
+
344
+ end
345
+
346
+ def self.checkServerStatus(vmid, shouldParams, baseUrl, apiKey)
347
+
348
+ begin
349
+ return compareServerStatus(vmid, shouldParams, baseUrl, apiKey)
350
+ rescue VagrantPlugins::Filoo::Errors::InvaildServerParameterError => e
351
+ raise VagrantPlugins::Filoo::Errors::UnexpectedStateError,
352
+ resource: SERVERSTATUS_RESOURCE,
353
+ state: e.serverStatus,
354
+ message: "Unexpected State of server " + serverStatus.to_json,
355
+ description: "Server with vmid #{vmid} should have following params set " + shouldParams.to_json
356
+ + " but has status " + e.serverStatus
357
+ end
358
+
359
+ end
360
+
361
+ #
362
+ # Retrieves the Server status and compares it with the given shouldPramams
363
+ #
364
+ def self.compareServerStatus(vmid, shouldParams, baseUrl, apiKey)
365
+ serverStatus = self.getServerStatus(vmid, baseUrl, apiKey)
366
+
367
+ if serverStatus == :not_created
368
+ raise VagrantPlugins::Filoo::Errors::UnexpectedStateError,
369
+ state: serverStatus,
370
+ message: "Unexpected State of server " + serverStatus.to_json
371
+ end
372
+
373
+ serverStatus = JSON.parse(serverStatus.to_json)
374
+ shouldParams = JSON.parse(shouldParams.to_json)
375
+ shouldParams.each do |key, value|
376
+
377
+ if "#{value}" != "#{serverStatus[key]}"
378
+ raise VagrantPlugins::Filoo::Errors::InvaildServerParameterError.new(key, serverStatus[key], serverStatus),
379
+ resource: SERVERSTATUS_RESOURCE,
380
+ invalidKey: key,
381
+ invalidValue: value,
382
+ state: serverStatus,
383
+ message: "Unexpected State of server " + serverStatus.to_json,
384
+ description: "Server with vmid #{vmid} should have following params set " + shouldParams.to_json
385
+ + " but has status " + serverStatus
386
+ end
387
+
388
+ end
389
+ return serverStatus
390
+ end
391
+
392
+ #images
393
+ IMAGES_RESOURCE = "/vserver/image"
394
+
395
+ def self.getAutoInstallImages(baseUrl, apiKey)
396
+ imageList = nil;
397
+ begin
398
+ imageList = self.call(baseUrl + IMAGES_RESOURCE, apiKey, {:action => "list"})['return']
399
+ rescue ArgumentError => e
400
+ raise ConfigError, e.message
401
+ end
402
+ autoInstallImagesHash = {}
403
+ imageList.each { |imageInfo|
404
+ if !imageInfo['cd'].nil? and imageInfo['autoinstall'] == 1
405
+ autoInstallImagesHash[imageInfo['cd']] = imageInfo['cd_imageid']
406
+ end
407
+ }
408
+ return autoInstallImagesHash;
409
+ end
410
+
411
+ #Image handling
412
+
413
+ def self.hashAutoInstallListFromImageList serverList
414
+ autoInstallImagesHash = {}
415
+ serverList.each { |imageInfo|
416
+ if !imageInfo['cd'].nil? and imageInfo['autoinstall'] == 1
417
+ autoInstallImagesHash[imageInfo['cd']] = imageInfo
418
+ autoInstallImagesHash[imageInfo['cd']].delete("cd")
419
+ end
420
+ }
421
+ return autoInstallImagesHash;
422
+ end
423
+
424
+
425
+ ##########################################
426
+ # basic api call handling to https://api.filoo.de/api/v1/
427
+ ############################################
428
+
429
+ SHOWJOB_RESOURCE = "/jobqueue/show/"
430
+ DEFAULT_TIMEOUT = 60
431
+
432
+ # asynchron calls
433
+ def self.call4JobId(url, apiKey, params)
434
+ apiCallPayload = nil
435
+ begin
436
+ apiCallPayload = self.call(url, apiKey, params)['return']
437
+ rescue ArgumentError => e
438
+ raise ConfigError, e.message
439
+ end
440
+ if !apiCallPayload.is_a?(Hash)
441
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
442
+ code: 500,
443
+ message: 'Unexpected return value to Api Call POST ' + url + ' ' + params.to_json,
444
+ description: 'Return value ' + apiCallPayload.to_json + ' is no a hash'
445
+ end
446
+ if apiCallPayload['jobid'].nil?
447
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
448
+ code: 500,
449
+ message: 'Unexpected return value to Api Call POST ' + url + ' ' + params.to_json,
450
+ description: 'Return value ' + apiCallPayload.to_json + ' has no field "jobid"'
451
+ end
452
+ apiCallPayload['jobid']
453
+ end
454
+
455
+
456
+ def self.waitJobDone(jobId, baseUrl, apiKey, timeout)
457
+ timeout = timeout.nil? ? DEFAULT_TIMEOUT : timeout
458
+ startTimeStamp = Time.now.to_f
459
+ result = nil;
460
+ while (result = requestJobStatusWithResult(jobId, baseUrl, apiKey)).nil?
461
+ if startTimeStamp - Time.now.to_f > timeout
462
+ raise Errors::FilooJobResultTimeoutError,
463
+ job_id: jobId,
464
+ timeout: timeout
465
+ end
466
+ sleep 3
467
+ end
468
+ result
469
+ end
470
+
471
+ def self.requestJobStatusWithResult(jobId, baseUrl, apiKey)
472
+ url = baseUrl + SHOWJOB_RESOURCE
473
+ params = {:jobid => jobId}
474
+ resp = nil
475
+ begin
476
+ resp = self.call(url, apiKey, {:jobid => jobId})
477
+ rescue ArgumentError => e
478
+ raise ConfigError, e.message
479
+ end
480
+ if resp['status']['description'] == "jobID not found"
481
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
482
+ code: 500,
483
+ message: "Unexpected return value to Api Call POST " + url + " " + {:jobid => jobId}.to_json,
484
+ code: 500,
485
+ description: "Requested jobid #{jobId} not found",
486
+ jobid: jobid
487
+ end
488
+ returnVal = resp['return']
489
+ if !returnVal.is_a?(Hash)
490
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
491
+ code: 500,
492
+ message: "Unexpected return value to Api Call POST " + url + " " + {:jobid => jobId}.to_json,
493
+ description: "Return value " + returnVal.to_json + " is not a Hash"
494
+ end
495
+ if returnVal['job_status'].nil?
496
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
497
+ code: 500,
498
+ message: "Unexpected return value to Api Call POST " + url + " " + {:jobid => jobId}.to_json,
499
+ description: 'JSON response ' + returnVal.to_json + ' has no Field "job_status"'
500
+ end
501
+ if returnVal['jobid'] != jobId
502
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
503
+ code: 500,
504
+ message: "Unexpected return value to Api Call POST " + url + " " + {:jobid => jobId}.to_json,
505
+ description: "Response references wrong jobid #{returnVal['jobid']} must refernce #{jobId}. Response: " + resp.to_json
506
+ end
507
+ if returnVal['job_param'].nil?
508
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
509
+ code: 500,
510
+ message: "Unexpected return value to Api Call POST " + url + " #{params} " + {:jobid => jobId}.to_json,
511
+ description: "Response has no field job_param in result. Response: " + returnVal.to_json
512
+ end
513
+ LOGGER.info("Filoo Job #{resp['return']['job_command']} #{resp['return']['job_status_text']}")
514
+ case returnVal['job_status_text']
515
+ when 'finished'
516
+ jobResult = nil
517
+ if !returnVal['job_result'].nil? and returnVal['job_result'] != ""
518
+ jobResult = JSON.parse(returnVal['job_result'])
519
+ end
520
+ return {:result => jobResult, :status => 'finished', jobid: jobId, job_command: returnVal['job_command'], job_param: returnVal['job_param']}
521
+ when 'failed', 'aborted'
522
+ raise VagrantPlugins::Filoo::Errors::FilooJobFailedError,
523
+ jobid: returnVal['jobid'],
524
+ job_command: returnVal['job_command'],
525
+ job_param: returnVal['job_param'],
526
+ message: "Job Execution Failed for Task #{returnVal['job_command']} with parameters #{returnVal['job_param']} and Job Id #{returnVal['jobid']}:" + resp.to_json
527
+ when 'new', 'processing'
528
+ return nil
529
+ end
530
+ end
531
+
532
+ # synchron call
533
+ def self.call(url, apiKey, params)
534
+ resp = doHttpCall(url, params, apiKey)
535
+ jsonResp = nil
536
+ begin
537
+ jsonResp = JSON.parse(resp.body)
538
+ rescue JSON::ParserError => e
539
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
540
+ code: 500,
541
+ message: "Can not parse JSON from response to POST " + url + " " + params.to_json,
542
+ description: "Can not parse " + resp.body + ": " + e.message
543
+ end
544
+ if !jsonResp['return'].nil?
545
+ return jsonResp
546
+ else
547
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
548
+ code: 500,
549
+ message: "No return field in response to POST " + url + " " + params.to_json,
550
+ description: "Response from api " + resp.body
551
+ end
552
+ return jsonResp
553
+ end
554
+
555
+ #http handling
556
+ def self.doHttpCall(url, params, apiKey)
557
+ if apiKey.nil? or apiKey == ""
558
+ raise ArgumentError, "filoo.filoo_api_key must be set"
559
+ end
560
+ if !(url =~ URI::regexp)
561
+ raise ArgumentError, "url must be a valid http resource but is #{url}"
562
+ end
563
+
564
+ boundary = createBoundary
565
+ headers = { Authorization: apiKey, :content_type => "multipart/form-data; boundary=----#{boundary}"}
566
+ body = createBody(params, boundary)
567
+ resp = nil
568
+ begin
569
+ resp = RestClient.post url, body, headers
570
+ rescue RestClient::BadRequest => e
571
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
572
+ code: e.http_code,
573
+ message: "Wrong parameter set #{params.to_json} on call to #{url}",
574
+ description: e.http_body
575
+
576
+ rescue RestClient::Unauthorized => e
577
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
578
+ code: e.http_code,
579
+ message: "Can not Authenticate with Api Key",
580
+ description: e.http_body
581
+
582
+ rescue RestClient::Forbidden => e
583
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
584
+ code: e.http_code,
585
+ message: "No Access granted on call to #{url} using parameters #{params.to_json}",
586
+ description: e.http_body
587
+
588
+ rescue RestClient::NotAcceptable => e
589
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
590
+ code: e.http_code,
591
+ message: "Async task triggered by call to #{url} using parameters #{params.to_json} is yet in queue",
592
+ description: e.http_body
593
+
594
+ rescue RestClient::RequestFailed => e
595
+ raise VagrantPlugins::Filoo::Errors::VagrantFilooError,
596
+ message: e.message
597
+ code -1
598
+ end
599
+
600
+ if resp.code != 200
601
+ raise VagrantPlugins::Filoo::Errors::FilooApiError,
602
+ code: jsonResp['status']['code'],
603
+ message: jsonResp['status']['message'],
604
+ description: jsonResp['status']['description']
605
+ end
606
+
607
+ return resp
608
+ end
609
+
610
+ def self.createBody(params, boundary)
611
+ body = ""
612
+ params.each do |name, value|
613
+ body = body + createPartFromParam(name, value, "------" + boundary)
614
+ end
615
+ body + "------" + boundary +"--"
616
+ end
617
+
618
+ def self.createPartFromParam(name, value, boundary)
619
+ "#{boundary}\nContent-Disposition: form-data; name=\"#{name}\"\n\n#{value}\n"
620
+ end
621
+
622
+ def self.createBoundary
623
+ random = ""; 16.times{random << ((rand(2)==1?65:97) + rand(25)).chr}
624
+ "VagrantFilooHttpClient#{random}"
625
+ end
626
+
627
+ end
628
+ end
629
+ end
@@ -0,0 +1,54 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module Filoo
5
+ class Config < Vagrant.plugin("2", :config)
6
+ # The access key ID for accessing Filoo.
7
+ #
8
+ # @return [String]
9
+ attr_accessor :filoo_api_key
10
+ attr_accessor :filoo_api_entry_point
11
+ attr_accessor :filoo_api_entry_point
12
+
13
+ attr_accessor :cd_image_name
14
+ attr_accessor :type
15
+ attr_accessor :cpu
16
+ attr_accessor :ram
17
+ attr_accessor :hdd
18
+ attr_accessor :additional_nic
19
+
20
+ def initialize()
21
+ @filoo_api_key = nil
22
+ @filoo_api_entry_point = nil
23
+ @cd_image_name = nil
24
+ @type = nil
25
+ @cpu = nil
26
+ @ram = nil
27
+ @hdd = nil
28
+ @additional_nic = nil
29
+ end
30
+
31
+ # set security_groups
32
+ def security_groups=(value)
33
+ # convert value to array if necessary
34
+ @security_groups = value.is_a?(Array) ? value : [value]
35
+ end
36
+
37
+ def finalize!
38
+ # Try to get access keys from standard FILOO environment variables; they
39
+ # will default to nil if the environment variables are not present.
40
+ @filoo_api_key = ENV['FILOO_API_KEY'] if @filoo_api_key == nil
41
+ @filoo_api_entry_point = ENV['FILOO_API_ENTRY_POINT'] if @filoo_api_entry_point == nil
42
+
43
+ #set default values for machine
44
+ @cd_image_name = 'Debian 7.7 - 64bit' if @cd_image_name == nil
45
+ @type = 'dynamic' if @type == nil
46
+ @cpu = 1 if @cpu == nil
47
+ @ram = 128 if @ram == nil
48
+ @hdd = 10 if @hdd == nil
49
+ @additional_nic = false if @additional_nic == nil
50
+ end
51
+
52
+ end
53
+ end
54
+ end