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.
- checksums.yaml +7 -0
- data/.gitignore +61 -0
- data/Gemfile +14 -0
- data/LICENSE +22 -0
- data/README.md +207 -0
- data/Rakefile +5 -0
- data/doc/img_res/filoo_logo.png +0 -0
- data/doc/img_res/filoo_wolke.png +0 -0
- data/example_box/README.md +13 -0
- data/example_box/metadata.json +3 -0
- data/filoo.box +0 -0
- data/lib/vagrant_filoo/action/create_server.rb +51 -0
- data/lib/vagrant_filoo/action/get_images.rb +21 -0
- data/lib/vagrant_filoo/action/is_created.rb +22 -0
- data/lib/vagrant_filoo/action/is_stopped.rb +18 -0
- data/lib/vagrant_filoo/action/message_already_created.rb +16 -0
- data/lib/vagrant_filoo/action/message_not_created.rb +16 -0
- data/lib/vagrant_filoo/action/read_ssh_info.rb +40 -0
- data/lib/vagrant_filoo/action/read_state.rb +65 -0
- data/lib/vagrant_filoo/action/start_instance.rb +48 -0
- data/lib/vagrant_filoo/action/stop_instance.rb +31 -0
- data/lib/vagrant_filoo/action/terminate_instance.rb +24 -0
- data/lib/vagrant_filoo/action/test.rb +2 -0
- data/lib/vagrant_filoo/action.rb +184 -0
- data/lib/vagrant_filoo/cloud_compute.rb +629 -0
- data/lib/vagrant_filoo/config.rb +54 -0
- data/lib/vagrant_filoo/errors.rb +81 -0
- data/lib/vagrant_filoo/plugin.rb +73 -0
- data/lib/vagrant_filoo/provider.rb +52 -0
- data/lib/vagrant_filoo/util/timer.rb +17 -0
- data/lib/vagrant_filoo/version.rb +5 -0
- data/lib/vagrant_filoo.rb +17 -0
- data/locales/en.yml +122 -0
- data/sample_config/Vagrantfile_example +23 -0
- data/spec/spec_helper.rb +0 -0
- data/spec/vagrant_filoo/config_spec.rb +70 -0
- data/templates/metadata.json.erb +3 -0
- data/templates/vagrant-filoo_package_Vagrantfile.erb +5 -0
- data/vagrant_filoo.gemspec +58 -0
- 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
|