vagrant-subutai 1.0.3 → 1.1.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/CHANGELOG.md +7 -0
- data/README.md +3 -2
- data/lib/vagrant-subutai.rb +33 -7
- data/lib/vagrant-subutai/blueprint/ansible_controller.rb +93 -0
- data/lib/vagrant-subutai/blueprint/environment_controller.rb +324 -0
- data/lib/vagrant-subutai/blueprint/variables_controller.rb +547 -0
- data/lib/vagrant-subutai/command.rb +84 -90
- data/lib/vagrant-subutai/config.rb +8 -43
- data/lib/vagrant-subutai/configs/configs.rb +179 -0
- data/lib/vagrant-subutai/models/ansible.rb +18 -0
- data/lib/vagrant-subutai/models/console/container.rb +27 -0
- data/lib/vagrant-subutai/models/console/environment.rb +16 -0
- data/lib/vagrant-subutai/models/container.rb +34 -0
- data/lib/vagrant-subutai/models/domain.rb +11 -0
- data/lib/vagrant-subutai/models/environment.rb +13 -0
- data/lib/vagrant-subutai/packer/subutai_config.rb +17 -1
- data/lib/vagrant-subutai/plugin.rb +10 -3
- data/lib/vagrant-subutai/provisioner.rb +63 -0
- data/lib/vagrant-subutai/put.rb +21 -0
- data/lib/vagrant-subutai/rest/bazaar.rb +141 -0
- data/lib/vagrant-subutai/rest/gorjun.rb +40 -0
- data/lib/vagrant-subutai/rest/subutai_console.rb +189 -0
- data/lib/vagrant-subutai/subutai_commands.rb +250 -122
- data/lib/vagrant-subutai/version.rb +1 -1
- metadata +18 -6
- data/Vagrantfile +0 -7
- data/lib/vagrant-subutai/models/resource_host.rb +0 -7
- data/lib/vagrant-subutai/rest.rb +0 -77
- data/lib/vagrant-subutai/rh_controller.rb +0 -32
@@ -0,0 +1,547 @@
|
|
1
|
+
require_relative '../../vagrant-subutai'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module VagrantSubutai
|
5
|
+
module Blueprint
|
6
|
+
class VariablesController
|
7
|
+
attr_accessor :json,
|
8
|
+
:variables,
|
9
|
+
:required_ram, # sum of all containers ram size required (in unit GB)
|
10
|
+
:required_disk, # sum of all containers disk size required (in unit GB)
|
11
|
+
:available_ram, # sum of all containers ram size free (in unit GB)
|
12
|
+
:available_disk, # sum of all containers disk size free (in unit GB)
|
13
|
+
:mode, # Environment build mode (peer, bazaar)
|
14
|
+
:cookies # Bazaar cookies(for reserving domain)
|
15
|
+
|
16
|
+
KEYS = {
|
17
|
+
name: 'name',
|
18
|
+
description: 'description',
|
19
|
+
containers: 'containers',
|
20
|
+
hostname: 'hostname',
|
21
|
+
template: 'template',
|
22
|
+
size: 'size',
|
23
|
+
peer_criteria: 'peer-criteria',
|
24
|
+
port_mapping: 'port-mapping',
|
25
|
+
protocol: 'protocol',
|
26
|
+
domain: 'domain',
|
27
|
+
internal_port: 'internal-port',
|
28
|
+
external_port: 'external-port',
|
29
|
+
max_price: 'max-price',
|
30
|
+
avg_cpu_load: 'avg-cpu-load',
|
31
|
+
min_free_ram: 'min-free-ram',
|
32
|
+
min_free_disk_space: 'min-free-disk-space',
|
33
|
+
user_variables: 'user-variables',
|
34
|
+
type: 'type',
|
35
|
+
default: 'default',
|
36
|
+
validation: 'validation',
|
37
|
+
ansible_configuration: 'ansible-configuration',
|
38
|
+
extra_vars: 'extra-vars',
|
39
|
+
key: 'key',
|
40
|
+
value: 'value',
|
41
|
+
source_url: 'source-url',
|
42
|
+
ansible_playbook: 'ansible-playbook',
|
43
|
+
groups: 'groups',
|
44
|
+
hostnames: 'hostnames'
|
45
|
+
}.freeze
|
46
|
+
|
47
|
+
# @params available_ram, available_disk
|
48
|
+
def initialize(available_ram, available_disk, mode)
|
49
|
+
@required_ram = 0
|
50
|
+
@required_disk = 0
|
51
|
+
@available_ram = available_ram
|
52
|
+
@available_disk = available_disk
|
53
|
+
@mode = mode
|
54
|
+
|
55
|
+
begin
|
56
|
+
@json = JSON.parse(File.read("#{Dir.pwd}/#{Configs::Blueprint::FILE_NAME}"))
|
57
|
+
rescue => e
|
58
|
+
Put.error e
|
59
|
+
exit!
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Gives Subutai.json user variables
|
64
|
+
# returns json object
|
65
|
+
def user_variables
|
66
|
+
hash = {}
|
67
|
+
|
68
|
+
if @json.key?(KEYS[:user_variables])
|
69
|
+
conf_user_variables = SubutaiConfig.get(:USER_VARIABLES)
|
70
|
+
|
71
|
+
if conf_user_variables.nil?
|
72
|
+
conf_user_variables = {}
|
73
|
+
else
|
74
|
+
if conf_user_variables.kind_of?(String)
|
75
|
+
begin
|
76
|
+
conf_user_variables = JSON.parse(SubutaiConfig.get(:USER_VARIABLES))
|
77
|
+
rescue JSON::ParserError => e
|
78
|
+
Put.error e
|
79
|
+
return
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
user_variables = @json[KEYS[:user_variables]]
|
85
|
+
keys = user_variables.keys
|
86
|
+
|
87
|
+
keys.each do |key|
|
88
|
+
if conf_user_variables[key].nil?
|
89
|
+
hash[key] = get_input(user_variables[key])
|
90
|
+
else
|
91
|
+
hash[key] = conf_user_variables[key]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
@variables = hash
|
97
|
+
end
|
98
|
+
|
99
|
+
# This counts how mach quota(ram, disk) required for building environment from the Peer Os
|
100
|
+
def check_required_quota
|
101
|
+
if @json.key?(KEYS[:user_variables])
|
102
|
+
user_variables = @json[KEYS[:user_variables]]
|
103
|
+
keys = user_variables.keys
|
104
|
+
|
105
|
+
keys.each do |key|
|
106
|
+
if user_variables[key][KEYS[:type]] == 'enum' && Configs::Blueprint::CONTAINER_SIZES.include?(user_variables[key][KEYS[:default]])
|
107
|
+
@required_ram += (VagrantSubutai::Configs::Quota::RESOURCE[(user_variables[key][KEYS[:default]]).strip.to_sym][:RAM])
|
108
|
+
@required_disk += (VagrantSubutai::Configs::Quota::RESOURCE[(user_variables[key][KEYS[:default]]).strip.to_sym][:DISK])
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
@required_ram += VagrantSubutai::Configs::Quota::RESOURCE[:TINY][:RAM] if @json.key?(KEYS[:ansible_configuration]) # default ansible container ram
|
113
|
+
@required_disk += VagrantSubutai::Configs::Quota::RESOURCE[:TINY][:DISK] if @json.key?(KEYS[:ansible_configuration]) # default ansible container disk
|
114
|
+
else
|
115
|
+
@json[KEYS[:containers]].each do |container|
|
116
|
+
@required_ram += (VagrantSubutai::Configs::Quota::RESOURCE[(container[KEYS[:size]]).to_sym][:RAM])
|
117
|
+
@required_disk += (VagrantSubutai::Configs::Quota::RESOURCE[(container[KEYS[:size]]).to_sym][:DISK])
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def check_quota?(resource)
|
123
|
+
resource = JSON.parse(resource)
|
124
|
+
|
125
|
+
@free_ram = resource['RAM']['free'].to_f / 1073741824 # convert bytes to gb
|
126
|
+
@free_disk = (resource['Disk']['total'].to_f - resource['Disk']['used'].to_f) / 1073741824 # convert bytes to gb
|
127
|
+
|
128
|
+
@free_ram = @free_ram.round(3)
|
129
|
+
@free_disk = @free_disk.round(2)
|
130
|
+
|
131
|
+
check_required_quota
|
132
|
+
|
133
|
+
if @free_ram >= @required_ram && @free_disk >= @required_disk
|
134
|
+
true
|
135
|
+
else
|
136
|
+
Put.warn "\nNo available resources on the Peer Os\n"
|
137
|
+
Put.info "--------------------------------------------------------------------"
|
138
|
+
if @free_ram >= @required_ram
|
139
|
+
Put.info "RAM: available = #{@free_ram} gb, required minimum = #{@required_ram} gb"
|
140
|
+
else
|
141
|
+
Put.error "RAM: available = #{@free_ram} gb, required minimum = #{@required_ram} gb"
|
142
|
+
end
|
143
|
+
|
144
|
+
Put.info "--------------------------------------------------------------------"
|
145
|
+
|
146
|
+
if @free_disk >= @required_disk
|
147
|
+
Put.info "DISK: available = #{@free_disk} gb, required minimum = #{@required_disk} gb"
|
148
|
+
else
|
149
|
+
Put.error "DISK: available = #{@free_disk} gb, required minimum = #{@required_disk} gb"
|
150
|
+
end
|
151
|
+
Put.info "--------------------------------------------------------------------"
|
152
|
+
|
153
|
+
false
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def has_ansible?
|
158
|
+
if @json.key?(KEYS[:ansible_configuration])
|
159
|
+
true
|
160
|
+
else
|
161
|
+
false
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def ansible
|
166
|
+
|
167
|
+
if has_ansible?
|
168
|
+
ansible = VagrantSubutai::Models::Ansible.new
|
169
|
+
ansible_configuration = @json[KEYS[:ansible_configuration]]
|
170
|
+
|
171
|
+
ansible.ansible_playbook = ansible_configuration[KEYS[:ansible_playbook]]
|
172
|
+
ansible.source_url = ansible_configuration[KEYS[:source_url]]
|
173
|
+
ansible.extra_vars = []
|
174
|
+
ansible.groups = []
|
175
|
+
|
176
|
+
ansible_configuration[KEYS[:groups]].each do |group|
|
177
|
+
temp = group
|
178
|
+
hostnames = []
|
179
|
+
|
180
|
+
group[KEYS[:hostnames]].each do |hostname|
|
181
|
+
hostnames << value(hostname)
|
182
|
+
end
|
183
|
+
temp[KEYS[:hostnames]] = hostnames
|
184
|
+
ansible.groups << temp
|
185
|
+
end
|
186
|
+
|
187
|
+
if ansible_configuration.key?(KEYS[:extra_vars])
|
188
|
+
ansible_configuration[KEYS[:extra_vars]].each do |obj|
|
189
|
+
hash = {}
|
190
|
+
hash[obj[KEYS[:key]]] = value(obj[KEYS[:value]])
|
191
|
+
ansible.extra_vars << hash
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
ansible
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def params(rh_id, peer_id)
|
200
|
+
env = environment
|
201
|
+
containers = env.containers
|
202
|
+
|
203
|
+
hash = {}
|
204
|
+
nodes = []
|
205
|
+
|
206
|
+
if mode == Configs::Blueprint::MODE::PEER
|
207
|
+
containers.each do |container|
|
208
|
+
node = {}
|
209
|
+
node['hostname'] = container.hostname
|
210
|
+
node['quota'] = {'containerSize' => container.container_size}
|
211
|
+
node['templateId'] = Rest::Gorjun.template_id(container.name, container.owner)
|
212
|
+
node['resourceHostId'] = rh_id
|
213
|
+
node['peerId'] = peer_id
|
214
|
+
nodes << node
|
215
|
+
end
|
216
|
+
|
217
|
+
hash['name'] = env.name
|
218
|
+
hash['sshKey'] = ""
|
219
|
+
hash['nodes'] = nodes
|
220
|
+
elsif mode == Configs::Blueprint::MODE::BAZAAR
|
221
|
+
containers.each do |container|
|
222
|
+
node = {}
|
223
|
+
node['hostname'] = container.hostname
|
224
|
+
node['quota'] = {'containerSize' => container.container_size}
|
225
|
+
node['templateId'] = Rest::Gorjun.template_id(container.name, container.owner)
|
226
|
+
node['resourceHostId'] = rh_id
|
227
|
+
node['templateName'] = container.name
|
228
|
+
node['peerId'] = peer_id
|
229
|
+
nodes << node
|
230
|
+
end
|
231
|
+
|
232
|
+
hash['environmentName'] = env.name
|
233
|
+
hash['exchangeSshKeys'] = true
|
234
|
+
hash['registerHosts'] = true
|
235
|
+
hash['nodes'] = nodes
|
236
|
+
end
|
237
|
+
|
238
|
+
|
239
|
+
hash
|
240
|
+
end
|
241
|
+
|
242
|
+
def value(variable)
|
243
|
+
if is_variable?(variable)
|
244
|
+
@variables[variable[/\${(.*?)}/, 1]]
|
245
|
+
else
|
246
|
+
variable
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def is_variable?(var)
|
251
|
+
if (var =~ /\${(.*?)}/).nil?
|
252
|
+
false
|
253
|
+
else
|
254
|
+
true
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
# Environment
|
259
|
+
# @return Environment model
|
260
|
+
def environment
|
261
|
+
env = VagrantSubutai::Models::Environment.new
|
262
|
+
env.name = value(@json[KEYS[:name]])
|
263
|
+
env.containers = containers
|
264
|
+
env
|
265
|
+
end
|
266
|
+
|
267
|
+
# Containers
|
268
|
+
# @return Container Models
|
269
|
+
def containers
|
270
|
+
arr = []
|
271
|
+
|
272
|
+
@json[KEYS[:containers]].each do |container|
|
273
|
+
cont = VagrantSubutai::Models::Container.new
|
274
|
+
|
275
|
+
cont.hostname = value(container[KEYS[:hostname]])
|
276
|
+
cont.container_size = value(container[KEYS[:size]])
|
277
|
+
cont.template = container[KEYS[:template]]
|
278
|
+
cont.peer_criteria = container[KEYS[:peer_criteria]]
|
279
|
+
cont.port_mapping = container[KEYS[:port_mapping]]
|
280
|
+
|
281
|
+
arr << cont
|
282
|
+
end
|
283
|
+
|
284
|
+
if @json.key?(KEYS[:ansible_configuration])
|
285
|
+
cont = VagrantSubutai::Models::Container.new
|
286
|
+
cont.ansible
|
287
|
+
arr << cont
|
288
|
+
end
|
289
|
+
|
290
|
+
arr
|
291
|
+
end
|
292
|
+
|
293
|
+
# Domain
|
294
|
+
# @return Domain Model or nil
|
295
|
+
def domain
|
296
|
+
@json[KEYS[:containers]].each do |container|
|
297
|
+
if container.key?(KEYS[:port_mapping])
|
298
|
+
container[KEYS[:port_mapping]].each do |port_map|
|
299
|
+
if port_map[KEYS[:protocol]] == 'HTTP' || port_map[KEYS[:protocol]] == 'http'
|
300
|
+
domain = VagrantSubutai::Models::Domain.new
|
301
|
+
|
302
|
+
domain.protocol = port_map[KEYS[:protocol]]
|
303
|
+
domain.name = value(port_map[KEYS[:domain]])
|
304
|
+
domain.internal_port = port_map[KEYS[:internal_port]]
|
305
|
+
domain.external_port = port_map[KEYS[:external_port]]
|
306
|
+
domain.container_hostname = value(container[KEYS[:hostname]])
|
307
|
+
|
308
|
+
return domain
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
nil
|
315
|
+
end
|
316
|
+
|
317
|
+
# Gets input variable
|
318
|
+
# @params variable json object
|
319
|
+
def get_input(variable_json)
|
320
|
+
if variable_json[KEYS[:type]] == 'enum'
|
321
|
+
Put.info "\nEnter your container size (Ex: #{variable_json[KEYS[:default]]}): "
|
322
|
+
validations = variable_json[KEYS[:validation]].split(',')
|
323
|
+
|
324
|
+
temp = nil
|
325
|
+
validations.each_with_index do |validation, index|
|
326
|
+
if @available_ram >= Configs::Quota::RESOURCE[validation.strip.to_sym][:RAM] && @available_disk >= Configs::Quota::RESOURCE[validation.strip.to_sym][:DISK]
|
327
|
+
Put.info " #{index}. #{validation}"
|
328
|
+
temp = index
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
Put.info "\nChoose your container size between ( 0 to #{temp}): "
|
333
|
+
input = STDIN.gets.strip.to_i
|
334
|
+
validations[input]
|
335
|
+
elsif mode == Configs::Blueprint::MODE::BAZAAR && variable_json[KEYS[:type]] == 'domain'
|
336
|
+
Put.info "\n#Create a new domain: (Ex: YOUR_DOMAIN_NAME.envs.subutai.cloud)"
|
337
|
+
reserve
|
338
|
+
else
|
339
|
+
Put.info "\n#{variable_json[KEYS[:description]]}: (Ex: #{variable_json[KEYS[:default]]})"
|
340
|
+
|
341
|
+
STDIN.gets.strip
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
def reserve
|
346
|
+
begin
|
347
|
+
@temp = STDIN.gets.strip
|
348
|
+
@response = VagrantSubutai::Rest::Bazaar.reserve(@cookies, @temp)
|
349
|
+
|
350
|
+
until @response.kind_of?(Net::HTTPOK)
|
351
|
+
Put.warn "\n-------------------------------------------------------------------"
|
352
|
+
Put.warn "Requested \"#{@temp}.envs.subutai.cloud\" sub-domain already exists"
|
353
|
+
Put.warn '-------------------------------------------------------------------'
|
354
|
+
|
355
|
+
Put.info "\n#Create a new domain: (Ex: YOUR_DOMAIN_NAME.envs.subutai.cloud)"
|
356
|
+
@temp = STDIN.gets.strip
|
357
|
+
@response = VagrantSubutai::Rest::Bazaar.reserve(@cookies, @temp)
|
358
|
+
end
|
359
|
+
|
360
|
+
res = VagrantSubutai::Rest::Bazaar.domains(@cookies)
|
361
|
+
json = JSON.parse(res.body)
|
362
|
+
|
363
|
+
json = json.find {|domain| domain['name'].split('.').first == @temp}
|
364
|
+
|
365
|
+
Put.info "\n Created a new domain: #{json['name']}"
|
366
|
+
|
367
|
+
json['name']
|
368
|
+
rescue => e
|
369
|
+
Put.error e
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
# Validate variable
|
374
|
+
# @params var, type, validation
|
375
|
+
def validate_variable(var, variable_json)
|
376
|
+
if (var =~ /#{Regexp.quote(variable_json[KEYS[:validation]])}/).nil?
|
377
|
+
false
|
378
|
+
else
|
379
|
+
true
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
def bazaar_params(variables)
|
384
|
+
variables.each do |variable|
|
385
|
+
Put.info variable['label']
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
def get_input_bazaar(variable)
|
390
|
+
Put.info "\n#{variable['label']}"
|
391
|
+
if variable.key?('acceptableValues')
|
392
|
+
if variable['type'] == 'enum'
|
393
|
+
arr = variable['acceptableValues'].split(',')
|
394
|
+
temp = nil
|
395
|
+
|
396
|
+
arr.each_with_index do |val, index|
|
397
|
+
Put.info " #{index}. #{val}"
|
398
|
+
temp = index
|
399
|
+
end
|
400
|
+
|
401
|
+
Put.info "\nChoose your container size between ( 0 to #{temp}): "
|
402
|
+
input = STDIN.gets.strip.to_i
|
403
|
+
arr[input]
|
404
|
+
elsif variable['type'] == 'domain'
|
405
|
+
arr = variable['acceptableValues'].split(',')
|
406
|
+
temp = nil
|
407
|
+
|
408
|
+
arr.each_with_index do |val, index|
|
409
|
+
Put.info " #{index}. #{val}"
|
410
|
+
temp = index
|
411
|
+
end
|
412
|
+
Put.info " #{temp+1}. Create a new domain: (Ex: YOUR_DOMAIN_NAME.envs.subutai.cloud)"
|
413
|
+
|
414
|
+
Put.info "\nChoose options: ( 0 to #{temp+1}) "
|
415
|
+
input = STDIN.gets.strip.to_i
|
416
|
+
|
417
|
+
if temp+1 == input
|
418
|
+
Put.success "\nCreate a new domain: (Ex: YOUR_DOMAIN_NAME.envs.subutai.cloud)"
|
419
|
+
reserve
|
420
|
+
else
|
421
|
+
Put.success "\n Chosen a domain: #{arr[input]}"
|
422
|
+
arr[input]
|
423
|
+
end
|
424
|
+
|
425
|
+
end
|
426
|
+
else
|
427
|
+
STDIN.gets.strip
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
# Validates Subutai.json file
|
432
|
+
def validate
|
433
|
+
scheme = Configs::Blueprint::SCHEME
|
434
|
+
|
435
|
+
# Check keys
|
436
|
+
@json.keys.each do |key|
|
437
|
+
unless scheme.key?(key.to_sym)
|
438
|
+
Put.error "Undefined key: \"#{key}\""
|
439
|
+
return false
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
scheme_container = scheme[:containers].first
|
444
|
+
scheme_port_mapping = scheme_container[KEYS[:port_mapping].to_sym].first
|
445
|
+
# Check container keys
|
446
|
+
@json[KEYS[:containers]].each do |container|
|
447
|
+
container.keys.each do |key|
|
448
|
+
unless scheme_container.key?(key.to_sym)
|
449
|
+
Put.error "Undefined key: \"#{key}\""
|
450
|
+
return false
|
451
|
+
end
|
452
|
+
|
453
|
+
if key == KEYS[:size] && !is_variable?(container[KEYS[:size]])
|
454
|
+
unless Configs::Blueprint::CONTAINER_SIZES.include?(container[KEYS[:size]])
|
455
|
+
Put.error "Undefined container size: #{container[KEYS[:size]]}"
|
456
|
+
return false
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
if container.key?(KEYS[:port_mapping])
|
461
|
+
container[KEYS[:port_mapping]].each do |port_map|
|
462
|
+
port_map.keys.each do |key|
|
463
|
+
unless scheme_port_mapping.key?(key.to_sym)
|
464
|
+
Put.error "Undefined port-mapping key: #{key}"
|
465
|
+
return false
|
466
|
+
end
|
467
|
+
end
|
468
|
+
end
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
# Check ansible configuration
|
474
|
+
if @json.key?(KEYS[:ansible_configuration])
|
475
|
+
@json[KEYS[:ansible_configuration]].keys.each do |key|
|
476
|
+
unless scheme[KEYS[:ansible_configuration].to_sym].key?(key.to_sym)
|
477
|
+
Put.error "Undefined ansible-configuration key: #{key}"
|
478
|
+
return false
|
479
|
+
end
|
480
|
+
end
|
481
|
+
|
482
|
+
# check extra-vars
|
483
|
+
if @json[KEYS[:ansible_configuration]].key?(KEYS[:extra_vars])
|
484
|
+
unless @json[KEYS[:ansible_configuration]][KEYS[:extra_vars]].kind_of?(Array)
|
485
|
+
Put.error "ansible-configuration extra-vals should be JSON array \"[]\""
|
486
|
+
return false
|
487
|
+
end
|
488
|
+
|
489
|
+
@json[KEYS[:ansible_configuration]][KEYS[:extra_vars]].each do |extra_var|
|
490
|
+
unless extra_var.key?(KEYS[:key])
|
491
|
+
Put.error "ansible-configuration extra-vals has no \"key\" key"
|
492
|
+
return false
|
493
|
+
end
|
494
|
+
|
495
|
+
unless extra_var.key?(KEYS[:value])
|
496
|
+
Put.error "ansible-configuration extra-vals has no \"value\" key"
|
497
|
+
return false
|
498
|
+
end
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
# check groups
|
503
|
+
if @json[KEYS[:ansible_configuration]].key?(KEYS[:groups])
|
504
|
+
unless @json[KEYS[:ansible_configuration]][KEYS[:groups]].kind_of?(Array)
|
505
|
+
Put.error "groups should be JSON array"
|
506
|
+
return false
|
507
|
+
end
|
508
|
+
|
509
|
+
@json[KEYS[:ansible_configuration]][KEYS[:groups]].each do |group|
|
510
|
+
group.keys.each do |key|
|
511
|
+
unless scheme[KEYS[:ansible_configuration].to_sym][KEYS[:groups].to_sym].first.key?(key.to_sym)
|
512
|
+
Put.error "Undefined groups key: #{key}"
|
513
|
+
return false
|
514
|
+
end
|
515
|
+
end
|
516
|
+
end
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
# check peer criteria
|
521
|
+
@json[KEYS[:peer_criteria]].each do |peer_criteria|
|
522
|
+
peer_criteria.keys.each do |key|
|
523
|
+
unless scheme[KEYS[:peer_criteria].to_sym].first.key?(key.to_sym)
|
524
|
+
Put.error "Undefined peer-criteria key: #{key}"
|
525
|
+
return false
|
526
|
+
end
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
# check user-variables
|
531
|
+
if @json.key?(KEYS[:user_variables])
|
532
|
+
@json[KEYS[:user_variables]].keys.each do |key|
|
533
|
+
user_variable = @json[KEYS[:user_variables]][key]
|
534
|
+
user_variable.keys.each do |key|
|
535
|
+
unless scheme[KEYS[:user_variables].to_sym][:any_name].key?(key.to_sym)
|
536
|
+
Put.error "Undefined user-variables key: #{key}"
|
537
|
+
return false
|
538
|
+
end
|
539
|
+
end
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
true
|
544
|
+
end
|
545
|
+
end
|
546
|
+
end
|
547
|
+
end
|