vagrant_filoo 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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