dtk-client 0.6.8 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +8 -8
  2. data/bin/dtk +5 -1
  3. data/lib/auxiliary.rb +0 -1
  4. data/lib/commands/common/thor/assembly_workspace.rb +20 -1
  5. data/lib/commands/common/thor/inventory_parser.rb +1 -1
  6. data/lib/commands/common/thor/module/import.rb +41 -106
  7. data/lib/commands/common/thor/module.rb +13 -226
  8. data/lib/commands/common/thor/poller.rb +48 -0
  9. data/lib/commands/common/thor/puppet_forge.rb +7 -1
  10. data/lib/commands/common/thor/purge_clone.rb +2 -1
  11. data/lib/commands/common/thor/task_status.rb +15 -14
  12. data/lib/commands/common/thor/test_action_agent.rb +39 -0
  13. data/lib/commands/thor/component_module.rb +2 -2
  14. data/lib/commands/thor/node.rb +55 -14
  15. data/lib/commands/thor/node_group.rb +2 -26
  16. data/lib/commands/thor/service.rb +31 -11
  17. data/lib/commands/thor/service_module.rb +3 -1
  18. data/lib/commands/thor/workspace.rb +13 -3
  19. data/lib/core.rb +16 -6
  20. data/lib/domain/git_adapter.rb +0 -3
  21. data/lib/domain/response.rb +25 -13
  22. data/lib/dtk-client/version.rb +1 -1
  23. data/lib/parser/adapters/thor.rb +8 -5
  24. data/lib/shell/context.rb +8 -19
  25. data/lib/shell/domain/active_context.rb +169 -0
  26. data/lib/shell/domain/context_entity.rb +72 -0
  27. data/lib/shell/domain/context_params.rb +202 -0
  28. data/lib/shell/domain/override_tasks.rb +71 -0
  29. data/lib/shell/domain/shadow_entity.rb +59 -0
  30. data/lib/shell/help_monkey_patch.rb +76 -71
  31. data/lib/shell/message_queue.rb +2 -0
  32. data/lib/shell/status_monitor.rb +5 -3
  33. data/lib/shell.rb +4 -2
  34. data/lib/util/dtk_puppet.rb +8 -6
  35. data/lib/util/os_util.rb +5 -1
  36. data/lib/view_processor/table_print.rb +67 -12
  37. data/spec/lib/spec_thor.rb +5 -2
  38. metadata +9 -3
  39. data/lib/shell/domain.rb +0 -492
data/lib/shell/domain.rb DELETED
@@ -1,492 +0,0 @@
1
- module DTK
2
- module Shell
3
-
4
- class ContextParams
5
-
6
- attr_accessor :current_context
7
- attr_accessor :method_arguments
8
-
9
- def initialize(override_method_arguments = [])
10
- @current_context = ActiveContext.new
11
- @method_arguments = override_method_arguments
12
- @thor_options = Hash.new
13
- end
14
-
15
- def add_context_to_params(context_name, entity_name, context_value = nil)
16
- @current_context.push_new_context(context_name, stand_name(entity_name), context_value)
17
- end
18
-
19
- def add_context_name_to_params(context_name, entity_name, context_value = nil)
20
- @current_context.push_new_name_context(context_name, stand_name(entity_name), context_value)
21
- end
22
-
23
- def forward_options(options)
24
- @thor_options = options
25
- end
26
-
27
- def get_forwarded_options()
28
- @thor_options
29
- end
30
-
31
- def get_forwarded_thor_option(option_key)
32
- return @thor_options ? @thor_options[option_key] : nil
33
- end
34
-
35
- def override_method_argument!(key, value)
36
- id = match_argument_id(key)
37
- raise DTK::Client::DtkImplementationError, "Wrong identifier used '#{key}', ID not matched!" unless id
38
- @method_arguments[id] = value
39
- end
40
-
41
- # can be class methods but no need, since we have this instance available in each method
42
- def retrieve_thor_options(mapping, options)
43
- results = []
44
- errors = []
45
-
46
- mapping.each do |key|
47
- required = key.to_s.match(/.+!$/)
48
- thor_key = key.to_s.gsub('!','')
49
-
50
- results << element = options[thor_key]
51
-
52
- if required && element.nil?
53
- errors << thor_key
54
- end
55
- end
56
-
57
- unless errors.empty?
58
- raise DTK::Client::DtkValidationError.new("Missing required option#{errors.size > 1 ? 's' : ''}: #{errors.join(', ')}", true)
59
- end
60
-
61
- return ((results.size == 1) ? results.first : results)
62
- end
63
-
64
- def retrieve_arguments(mapping, method_info = [])
65
- results = []
66
- errors = []
67
-
68
- # using context_name when have array as key_mapping [:assembly_id, :workspace_id]
69
- # to determine which context is used
70
- context_name = method_info.first.split('-').first unless method_info.empty?
71
-
72
- mapping.each do |key_mapping|
73
-
74
- is_array = key_mapping.is_a?(Array)
75
-
76
- selected_key = is_array ? key_mapping.first : key_mapping
77
-
78
- required = selected_key.to_s.match(/.+!$/)
79
-
80
- element = nil
81
- matched = selected_key.to_s.match(/option_([0-9]+)/)
82
- if matched
83
- id = matched[1].to_i - 1
84
- element = @method_arguments[id]
85
-
86
- # used if last parameter has more than one word
87
- # e.g. set-attribute attr_name "some value" (thor separates 'some value' as two parameters but we need it as one)
88
- if(mapping.last.to_s.eql?(key_mapping.to_s))
89
- new_id = id+1
90
- while @method_arguments[new_id] do
91
- element << " #{@method_arguments[new_id]}"
92
- new_id += 1;
93
- end
94
- end
95
-
96
- unless method_info.empty?
97
- unless element
98
- errors << method_info[id] if required
99
- end
100
- end
101
-
102
- else
103
- # More complex split regex for extracting entitiy name from mapping due to complex context names
104
- # i.e. assembly-template will have assembly_template_id mapping
105
- element = check_context_for_element(selected_key)
106
-
107
- # if we are dealing with array we need to check rest of the keys since it is OR
108
- # approach if first element not found take second
109
- if element.nil? && is_array
110
- key_mapping[1..-1].each do |alternative_key|
111
- element = check_context_for_element(alternative_key)
112
- break if element
113
- if context_name
114
- if alternative_key.to_s.include?(context_name.downcase)
115
- required = alternative_key.to_s.match(/.+!$/)
116
- selected_key = alternative_key
117
- end
118
- end
119
- end
120
- end
121
-
122
- unless element
123
- errors << "#{entity_name(selected_key).upcase} ID/NAME" if required
124
- end
125
- end
126
-
127
- results << element
128
- end
129
-
130
- unless errors.empty?
131
- raise DTK::Client::DtkValidationError.new("Missing required argument#{errors.size > 1 ? 's' : ''}: #{errors.join(', ')}", true)
132
- end
133
-
134
- return ((results.size == 1) ? results.first : results)
135
- end
136
-
137
- def is_last_command_eql_to?(command_name)
138
- return @current_context.last_command_name() == command_name.to_s
139
- end
140
-
141
- def is_there_identifier?(entity_name)
142
- return @current_context.find_identifier(entity_name) != nil
143
- end
144
-
145
- def is_there_command?(entity_name)
146
- return @current_context.find_command(entity_name) != nil
147
- end
148
- def current_command?
149
- return @current_context.current_command?
150
- end
151
- def root_command_name
152
- @current_context.first_command_name
153
- end
154
- def last_entity_name
155
- @current_context.last_context_entity_name
156
- end
157
-
158
- private
159
-
160
- # matches argument id (integer) from used identifier (symbol)
161
- #
162
- # Returns: Integer as ID , or nil if not found
163
- def match_argument_id(identifier)
164
- matched = identifier.to_s.match(/option_([0-9]+)/)
165
- (matched ? matched[1].to_i - 1 : nil)
166
- end
167
-
168
- # based on map key binding e.g. assembly_id, assembly_name we will extrace value
169
- # from our ActiveContext
170
- def check_context_for_element(key_mapping)
171
- split_info = split_info(key_mapping)
172
- entity_name = entity_name(key_mapping,split_info)
173
- id_type = split_info[1].gsub(/!/,'') # for required elements we remove '!' required marker
174
- context_identifier = @current_context.find_identifier(entity_name)
175
- if context_identifier
176
- return context_identifier.get_identifier(id_type)
177
- else
178
- return nil
179
- end
180
- end
181
-
182
- def entity_name(key_mapping,split_info=nil)
183
- split_info ||= split_info(key_mapping)
184
- split_info[0].gsub(/_/,'-') # makes sure we are using entity names with '_'
185
- end
186
-
187
- #
188
- # Standardize context name since we are in domain treating :component_module as :'component-module'
189
- # and need to be careful about these changes
190
- #
191
-
192
- def stand_name(name)
193
- name.to_s.gsub('_','-').to_sym
194
- end
195
-
196
- def split_info(key_mapping)
197
- key_mapping.to_s.split(/_([a-z]+!?$)/)
198
- end
199
-
200
- end
201
-
202
- class ContextEntity
203
- attr_accessor :entity
204
- attr_accessor :name
205
- attr_accessor :identifier
206
- attr_accessor :alt_identifier
207
-
208
- SHELL_SEPARATOR = '/'
209
-
210
- def self.create_context(context_name, entity_name, context_value=nil, type_id=:id)
211
- if context_value
212
- if :id.eql?(type_id)
213
- return ContextEntity.create_identifier(context_name, entity_name, context_value)
214
- else
215
- return ContextEntity.create_name_identifier(context_name, entity_name, context_value)
216
- end
217
- else
218
- return ContextEntity.create_command(context_name, entity_name)
219
- end
220
- end
221
-
222
- def is_identifier?
223
- return !@identifier.nil?
224
- end
225
-
226
- def is_alt_identifier?
227
- return !@alt_identifier.nil?
228
- end
229
-
230
- def is_command?
231
- return @identifier.nil?
232
- end
233
-
234
- def get_identifier(type)
235
- return (type == 'id' ? self.identifier : self.name)
236
- end
237
-
238
- def transform_alt_identifier_name()
239
- @name.gsub(Client::CommandBaseThor::ALT_IDENTIFIER_SEPARATOR, SHELL_SEPARATOR)
240
- end
241
-
242
- private
243
-
244
- def self.create_command(name, entity_name)
245
- instance = ContextEntity.new
246
- instance.name = name
247
- instance.entity = entity_name.to_sym
248
- return instance
249
- end
250
-
251
- def self.create_name_identifier(name, entity_name, value)
252
- instance = self.create_command(name,entity_name)
253
- instance.name = value
254
- instance.identifier = value
255
- instance.alt_identifier = value
256
- return instance
257
- end
258
-
259
- def self.create_identifier(name, entity_name, value)
260
- instance = self.create_command(name,entity_name)
261
- instance.identifier = value
262
- alt_identifier_name = name.to_s.split(Client::CommandBaseThor::ALT_IDENTIFIER_SEPARATOR)
263
- instance.alt_identifier = alt_identifier_name.size > 1 ? alt_identifier_name.first : nil
264
- return instance
265
- end
266
- end
267
-
268
- class ActiveContext
269
-
270
- # special case when we are not able to provide valid identifier but we are
271
- # using it as such
272
- NO_IDENTIFIER_PROVIDED = -1
273
-
274
- # TODO: Remove accessor for debug purpose only
275
- attr_accessor :context_list
276
-
277
- def clone_me()
278
- inst = ActiveContext.new
279
- inst.context_list = @context_list.clone
280
- return inst
281
- end
282
-
283
- def initialize
284
- @context_list = []
285
- end
286
-
287
- def push_new_context(context_name, entity_name, context_value=nil)
288
- @context_list << ContextEntity.create_context(context_name, entity_name, context_value)
289
- end
290
- def push_new_name_context(context_name, entity_name, context_value=nil)
291
- @context_list << ContextEntity.create_context(context_name, entity_name, context_value, :name)
292
- end
293
-
294
- def pop_context(n)
295
- return @context_list.pop(n)
296
- end
297
-
298
- def find_identifier(entity_name)
299
- results = @context_list.select { |e| (e.is_identifier? && (e.entity == entity_name.to_sym))}
300
- return results.first
301
- end
302
-
303
- def find_command(entity_name)
304
- results = @context_list.select { |e| (e.is_command? && (e.entity == entity_name.to_sym))}
305
- return results.first
306
- end
307
-
308
- def name_list()
309
- @context_list.collect { |e| e.is_alt_identifier? ? e.transform_alt_identifier_name : e.name }
310
- end
311
-
312
- def name_list_simple()
313
- @context_list.collect { |e| e.name }
314
- end
315
-
316
-
317
- # returns list of entities that have identifier
318
- def commands_that_have_identifiers()
319
- filtered_entities = @context_list.select { |e| e.is_identifier? }
320
- return filtered_entities.collect { |e| e.entity.to_s }
321
- end
322
-
323
- def command_list()
324
- filtered_entities = @context_list.select { |e| e.is_command? }
325
- return filtered_entities.collect { |e| e.entity.to_s }
326
- end
327
-
328
- # returns id to be used to retrive task list form the cache based on
329
- # current active context
330
- def get_task_cache_id()
331
- identifier = command_list().join('_')
332
- return 'dtk' if identifier.empty?
333
- if current_alt_identifier?
334
- return "#{identifier}_#{current_alt_identifier_name()}".to_sym()
335
- end
336
-
337
- return current_identifier? ? "#{identifier}_wid".to_sym : identifier.to_sym
338
- end
339
-
340
- def full_path()
341
- path = name_list().join('/')
342
- path = Context.enchance_path_with_alias(path, @context_list)
343
-
344
- return "/#{path}"
345
- end
346
-
347
- def clear()
348
- @context_list.clear
349
- end
350
-
351
- def empty?()
352
- return @context_list.empty?
353
- end
354
-
355
- def is_n_context?
356
- @context_list.size > 2
357
- end
358
-
359
- def is_base_context?
360
- @context_list.size == 1
361
- end
362
-
363
- def is_root_context?
364
- @context_list.size == 0
365
- end
366
-
367
- def current_command?
368
- return @context_list.empty? ? true : @context_list.last.is_command?
369
- end
370
-
371
- def current_identifier?
372
- return @context_list.empty? ? false : @context_list.last.is_identifier?
373
- end
374
-
375
- def current_alt_identifier?
376
- return @context_list.empty? ? false : @context_list.last.is_alt_identifier?
377
- end
378
-
379
- def current_alt_identifier_name
380
- @context_list.last.alt_identifier
381
- end
382
-
383
- def first_command_name()
384
- @context_list.each do |e|
385
- return e.name if e.is_command?
386
- end
387
-
388
- return nil
389
- end
390
-
391
- def is_there_identifier_for_first_context?
392
- @context_list.each { |e| return true if e.is_identifier? }
393
- return false
394
- end
395
-
396
- def last_command_name()
397
- @context_list.reverse.each do |e|
398
- return e.name if e.is_command?
399
- end
400
-
401
- return nil
402
- end
403
-
404
- def last_context_entity_name()
405
- return @context_list.empty? ? nil : @context_list.last.entity
406
- end
407
-
408
- def last_context_name()
409
- return @context_list.empty? ? nil : @context_list.last.name
410
- end
411
-
412
- def first_context_name()
413
- return @context_list.empty? ? nil : @context_list.first.name
414
- end
415
-
416
- def first_context()
417
- return @context_list.empty? ? nil : @context_list.first
418
- end
419
-
420
- def last_context()
421
- return @context_list.empty? ? nil : @context_list.last
422
- end
423
- end
424
-
425
- class CachedTasks < Hash
426
- end
427
-
428
- class OverrideTasks < Hash
429
-
430
- attr_accessor :completed_tasks
431
- attr_accessor :always_load_list
432
-
433
-
434
- # help_item (Thor printable task), structure:
435
- # [0] => task defintion
436
- # [1] => task description
437
- # [2] => task name
438
-
439
- # overriden_task (DTK override task), structure:
440
- # [0] => task name
441
- # [1] => task defintion
442
- # [2] => task description
443
-
444
- # using 'always load listed' to skip adding task to completed tasks e.g load utils for workspace and workspace_node
445
- def initialize(hash=nil, always_load_listed=[])
446
- super(hash)
447
- @completed_tasks = []
448
- @always_load_list = always_load_listed
449
- self.merge!(hash)
450
- end
451
-
452
- # returns true if there are overrides for tasks on first two levels.
453
- def are_there_self_override_tasks?
454
- return (self[:all][:self] || self[:command_only][:self] || self[:identifier_only][:self])
455
- end
456
-
457
- def check_help_item(help_item, is_command)
458
- command_tasks, identifier_tasks = get_all_tasks(:self)
459
- found = []
460
-
461
- if is_command
462
- found = command_tasks.select { |o_task| o_task[0].eql?(help_item[2]) }
463
- else
464
- found = identifier_tasks.select { |o_task| o_task[0].eql?(help_item[2]) }
465
- end
466
-
467
- # if we find self overriden task we remove it
468
- # [found.first[1],found.first[2],found.first[0]] => we convert from o_task structure to thor help structure
469
- return found.empty? ? help_item : [found.first[1],found.first[2],found.first[0]]
470
- end
471
-
472
- # returns 2 arrays one for commands and next one for identifiers
473
- def get_all_tasks(child_name)
474
- command_o_tasks, identifier_o_tasks = [], []
475
- command_o_tasks = (self[:all][child_name]||[]) + (self[:command_only][child_name]||[])
476
- identifier_o_tasks = (self[:all][child_name]||[]) + (self[:identifier_only][child_name]||[])
477
- return command_o_tasks, identifier_o_tasks
478
- end
479
-
480
- def is_completed?(child_name)
481
- # do not add task to completed if explicitly said to always load that task
482
- return false if @always_load_list.include?(child_name)
483
- @completed_tasks.include?(child_name)
484
- end
485
-
486
- def add_to_completed(child_name)
487
- @completed_tasks << child_name
488
- end
489
- end
490
-
491
- end
492
- end