dtk-client 0.5.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +5 -0
  3. data/Gemfile_dev +12 -0
  4. data/README.md +78 -0
  5. data/bin/dtk +54 -0
  6. data/bin/dtk-shell +15 -0
  7. data/dtk-client.gemspec +49 -0
  8. data/lib/auxiliary.rb +13 -0
  9. data/lib/bundler_monkey_patch.rb +9 -0
  10. data/lib/client.rb +48 -0
  11. data/lib/command_helper.rb +16 -0
  12. data/lib/command_helpers/git_repo.rb +391 -0
  13. data/lib/command_helpers/jenkins_client/config_xml.rb +271 -0
  14. data/lib/command_helpers/jenkins_client.rb +91 -0
  15. data/lib/command_helpers/service_importer.rb +99 -0
  16. data/lib/command_helpers/service_link.rb +18 -0
  17. data/lib/command_helpers/ssh_processing.rb +43 -0
  18. data/lib/commands/common/thor/assembly_workspace.rb +1089 -0
  19. data/lib/commands/common/thor/clone.rb +39 -0
  20. data/lib/commands/common/thor/common.rb +34 -0
  21. data/lib/commands/common/thor/edit.rb +168 -0
  22. data/lib/commands/common/thor/list_diffs.rb +84 -0
  23. data/lib/commands/common/thor/pull_clone_changes.rb +11 -0
  24. data/lib/commands/common/thor/pull_from_remote.rb +99 -0
  25. data/lib/commands/common/thor/purge_clone.rb +26 -0
  26. data/lib/commands/common/thor/push_clone_changes.rb +45 -0
  27. data/lib/commands/common/thor/push_to_remote.rb +45 -0
  28. data/lib/commands/common/thor/reparse.rb +36 -0
  29. data/lib/commands/common/thor/set_required_params.rb +29 -0
  30. data/lib/commands/common/thor/task_status.rb +81 -0
  31. data/lib/commands/thor/account.rb +213 -0
  32. data/lib/commands/thor/assembly.rb +329 -0
  33. data/lib/commands/thor/attribute.rb +62 -0
  34. data/lib/commands/thor/component.rb +52 -0
  35. data/lib/commands/thor/component_module.rb +829 -0
  36. data/lib/commands/thor/component_template.rb +153 -0
  37. data/lib/commands/thor/dependency.rb +18 -0
  38. data/lib/commands/thor/developer.rb +105 -0
  39. data/lib/commands/thor/dtk.rb +117 -0
  40. data/lib/commands/thor/library.rb +107 -0
  41. data/lib/commands/thor/node.rb +411 -0
  42. data/lib/commands/thor/node_group.rb +211 -0
  43. data/lib/commands/thor/node_template.rb +88 -0
  44. data/lib/commands/thor/project.rb +17 -0
  45. data/lib/commands/thor/provider.rb +155 -0
  46. data/lib/commands/thor/repo.rb +35 -0
  47. data/lib/commands/thor/service.rb +656 -0
  48. data/lib/commands/thor/service_module.rb +806 -0
  49. data/lib/commands/thor/state_change.rb +10 -0
  50. data/lib/commands/thor/target.rb +94 -0
  51. data/lib/commands/thor/task.rb +100 -0
  52. data/lib/commands/thor/utils.rb +4 -0
  53. data/lib/commands/thor/workspace.rb +437 -0
  54. data/lib/commands.rb +40 -0
  55. data/lib/config/cacert.pem +3785 -0
  56. data/lib/config/client.conf.header +18 -0
  57. data/lib/config/configuration.rb +82 -0
  58. data/lib/config/default.conf +14 -0
  59. data/lib/config/disk_cacher.rb +60 -0
  60. data/lib/configurator.rb +92 -0
  61. data/lib/context_router.rb +23 -0
  62. data/lib/core.rb +460 -0
  63. data/lib/domain/git_adapter.rb +221 -0
  64. data/lib/domain/response.rb +234 -0
  65. data/lib/dtk-client/version.rb +3 -0
  66. data/lib/dtk_constants.rb +23 -0
  67. data/lib/dtk_logger.rb +96 -0
  68. data/lib/error.rb +74 -0
  69. data/lib/git-logs/git.log +0 -0
  70. data/lib/parser/adapters/option_parser.rb +53 -0
  71. data/lib/parser/adapters/thor/common_option_defs.rb +12 -0
  72. data/lib/parser/adapters/thor.rb +509 -0
  73. data/lib/require_first.rb +87 -0
  74. data/lib/search_hash.rb +27 -0
  75. data/lib/shell/context.rb +975 -0
  76. data/lib/shell/context_aux.rb +29 -0
  77. data/lib/shell/domain.rb +447 -0
  78. data/lib/shell/header_shell.rb +27 -0
  79. data/lib/shell/help_monkey_patch.rb +221 -0
  80. data/lib/shell/interactive_wizard.rb +233 -0
  81. data/lib/shell/parse_monkey_patch.rb +22 -0
  82. data/lib/shell/status_monitor.rb +105 -0
  83. data/lib/shell.rb +219 -0
  84. data/lib/util/console.rb +143 -0
  85. data/lib/util/dtk_puppet.rb +46 -0
  86. data/lib/util/os_util.rb +265 -0
  87. data/lib/view_processor/augmented_simple_list.rb +27 -0
  88. data/lib/view_processor/hash_pretty_print.rb +106 -0
  89. data/lib/view_processor/simple_list.rb +139 -0
  90. data/lib/view_processor/table_print.rb +277 -0
  91. data/lib/view_processor.rb +112 -0
  92. data/puppet/manifests/init.pp +72 -0
  93. data/puppet/manifests/params.pp +16 -0
  94. data/puppet/r8meta.puppet.yml +18 -0
  95. data/puppet/templates/bash_profile.erb +2 -0
  96. data/puppet/templates/client.conf.erb +1 -0
  97. data/puppet/templates/dtkclient.erb +2 -0
  98. data/spec/assembly_spec.rb +50 -0
  99. data/spec/assembly_template_spec.rb +51 -0
  100. data/spec/component_template_spec.rb +40 -0
  101. data/spec/dependency_spec.rb +6 -0
  102. data/spec/dtk_shell_spec.rb +13 -0
  103. data/spec/dtk_spec.rb +33 -0
  104. data/spec/lib/spec_helper.rb +10 -0
  105. data/spec/lib/spec_thor.rb +105 -0
  106. data/spec/module_spec.rb +35 -0
  107. data/spec/node_spec.rb +43 -0
  108. data/spec/node_template_spec.rb +25 -0
  109. data/spec/project_spec.rb +6 -0
  110. data/spec/repo_spec.rb +7 -0
  111. data/spec/response_spec.rb +52 -0
  112. data/spec/service_spec.rb +41 -0
  113. data/spec/state_change_spec.rb +7 -0
  114. data/spec/table_print_spec.rb +48 -0
  115. data/spec/target_spec.rb +57 -0
  116. data/spec/task_spec.rb +28 -0
  117. data/views/assembly/augmented_simple_list.rb +12 -0
  118. data/views/assembly_template/augmented_simple_list.rb +12 -0
  119. data/views/list_task/augmented_simple_list.rb +12 -0
  120. metadata +351 -0
@@ -0,0 +1,29 @@
1
+ module DTK
2
+ module Shell
3
+ class ContextAux
4
+
5
+ class << self
6
+
7
+ def is_double_dot?(command)
8
+ return command.match(/\.\.[\/]?/)
9
+ end
10
+
11
+ # returns number of first '..' elements in array
12
+ def count_double_dots(entries)
13
+ double_dots_count = 0
14
+ # we check for '..' and remove them
15
+ entries.each do |e|
16
+ if is_double_dot?(e)
17
+ double_dots_count += 1
18
+ else
19
+ break
20
+ end
21
+ end
22
+
23
+ return double_dots_count
24
+ end
25
+
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,447 @@
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 = nil
13
+ end
14
+
15
+ def add_context_to_params(context_name, entity_name, context_value = nil)
16
+ @current_context.push_new_context(context_name, entity_name, context_value)
17
+ end
18
+
19
+ def forward_options(options)
20
+ @thor_options = options
21
+ end
22
+
23
+ def get_forwarded_options()
24
+ @thor_options
25
+ end
26
+
27
+ def get_forwarded_thor_option(option_key)
28
+ return @thor_options ? @thor_options[option_key] : nil
29
+ end
30
+
31
+ def override_method_argument!(key, value)
32
+ id = match_argument_id(key)
33
+ raise DTK::Client::DtkImplementationError, "Wrong identifier used '#{key}', ID not matched!" unless id
34
+ @method_arguments[id] = value
35
+ end
36
+
37
+ # can be class methods but no need, since we have this instance available in each method
38
+ def retrieve_thor_options(mapping, options)
39
+ results = []
40
+ errors = []
41
+
42
+ mapping.each do |key|
43
+ required = key.to_s.match(/.+!$/)
44
+ thor_key = key.to_s.gsub('!','')
45
+
46
+ results << element = options[thor_key]
47
+
48
+ if required && element.nil?
49
+ errors << thor_key
50
+ end
51
+ end
52
+
53
+ unless errors.empty?
54
+ raise DTK::Client::DtkValidationError.new("Missing required option#{errors.size > 1 ? 's' : ''}: #{errors.join(', ')}", true)
55
+ end
56
+
57
+ return ((results.size == 1) ? results.first : results)
58
+ end
59
+
60
+ def retrieve_arguments(mapping, method_info = [])
61
+ results = []
62
+ errors = []
63
+
64
+ # using context_name when have array as key_mapping [:assembly_id, :workspace_id]
65
+ # to determine which context is used
66
+ context_name = method_info.first.split('-').first unless method_info.empty?
67
+
68
+ mapping.each do |key_mapping|
69
+
70
+ is_array = key_mapping.is_a?(Array)
71
+
72
+ selected_key = is_array ? key_mapping.first : key_mapping
73
+
74
+ required = selected_key.to_s.match(/.+!$/)
75
+
76
+ element = nil
77
+ matched = selected_key.to_s.match(/option_([0-9]+)/)
78
+ if matched
79
+ id = matched[1].to_i - 1
80
+ element = @method_arguments[id]
81
+
82
+ unless method_info.empty?
83
+ unless element
84
+ errors << method_info[id] if required
85
+ end
86
+ end
87
+
88
+ else
89
+ # More complex split regex for extracting entitiy name from mapping due to complex context names
90
+ # i.e. assembly-template will have assembly_template_id mapping
91
+ element = check_context_for_element(selected_key)
92
+
93
+ # if we are dealing with array we need to check rest of the keys since it is OR
94
+ # approach if first element not found take second
95
+ if element.nil? && is_array
96
+ key_mapping[1..-1].each do |alternative_key|
97
+ element = check_context_for_element(alternative_key)
98
+ break if element
99
+ if context_name
100
+ if alternative_key.to_s.include?(context_name.downcase!)
101
+ required = alternative_key.to_s.match(/.+!$/)
102
+ selected_key = alternative_key
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ unless element
109
+ errors << "#{entity_name(selected_key).upcase} ID/NAME" if required
110
+ end
111
+ end
112
+
113
+ results << element
114
+ end
115
+
116
+ unless errors.empty?
117
+ raise DTK::Client::DtkValidationError.new("Missing required argument#{errors.size > 1 ? 's' : ''}: #{errors.join(', ')}", true)
118
+ end
119
+
120
+ return ((results.size == 1) ? results.first : results)
121
+ end
122
+
123
+ def is_last_command_eql_to?(command_name)
124
+ return @current_context.last_command_name() == command_name.to_s
125
+ end
126
+
127
+ def is_there_identifier?(entity_name)
128
+ return @current_context.find_identifier(entity_name) != nil
129
+ end
130
+
131
+ def is_there_command?(entity_name)
132
+ return @current_context.find_command(entity_name) != nil
133
+ end
134
+ def current_command?
135
+ return @current_context.current_command?
136
+ end
137
+ def root_command_name
138
+ @current_context.first_command_name
139
+ end
140
+ def last_entity_name
141
+ @current_context.last_context_entity_name
142
+ end
143
+
144
+ private
145
+
146
+ # matches argument id (integer) from used identifier (symbol)
147
+ #
148
+ # Returns: Integer as ID , or nil if not found
149
+ def match_argument_id(identifier)
150
+ matched = identifier.to_s.match(/option_([0-9]+)/)
151
+ (matched ? matched[1].to_i - 1 : nil)
152
+ end
153
+
154
+ # based on map key binding e.g. assembly_id, assembly_name we will extrace value
155
+ # from our ActiveContext
156
+ def check_context_for_element(key_mapping)
157
+ split_info = split_info(key_mapping)
158
+ entity_name = entity_name(key_mapping,split_info)
159
+ id_type = split_info[1].gsub(/!/,'') # for required elements we remove '!' required marker
160
+ context_identifier = @current_context.find_identifier(entity_name)
161
+ if context_identifier
162
+ return context_identifier.get_identifier(id_type)
163
+ else
164
+ return nil
165
+ end
166
+ end
167
+
168
+ def entity_name(key_mapping,split_info=nil)
169
+ split_info ||= split_info(key_mapping)
170
+ split_info[0].gsub(/_/,'-') # makes sure we are using entity names with '_'
171
+ end
172
+
173
+ def split_info(key_mapping)
174
+ key_mapping.to_s.split(/_([a-z]+!?$)/)
175
+ end
176
+
177
+ end
178
+
179
+ class ContextEntity
180
+ attr_accessor :entity
181
+ attr_accessor :name
182
+ attr_accessor :identifier
183
+ attr_accessor :alt_identifier
184
+
185
+ SHELL_SEPARATOR = '/'
186
+
187
+ def self.create_context(context_name, entity_name, context_value=nil)
188
+ if context_value
189
+ return ContextEntity.create_identifier(context_name, entity_name, context_value)
190
+ else
191
+ return ContextEntity.create_command(context_name, entity_name)
192
+ end
193
+ end
194
+
195
+ def is_identifier?
196
+ return !@identifier.nil?
197
+ end
198
+
199
+ def is_alt_identifier?
200
+ return !@alt_identifier.nil?
201
+ end
202
+
203
+ def is_command?
204
+ return @identifier.nil?
205
+ end
206
+
207
+ def get_identifier(type)
208
+ return (type == 'id' ? self.identifier : self.name)
209
+ end
210
+
211
+ def transform_alt_identifier_name()
212
+ @name.gsub(Client::CommandBaseThor::ALT_IDENTIFIER_SEPARATOR, SHELL_SEPARATOR)
213
+ end
214
+
215
+ private
216
+
217
+ def self.create_command(name, entity_name)
218
+ instance = ContextEntity.new
219
+ instance.name = name
220
+ instance.entity = entity_name.to_sym
221
+ return instance
222
+ end
223
+
224
+ def self.create_identifier(name, entity_name, value)
225
+ instance = self.create_command(name,entity_name)
226
+ instance.identifier = value
227
+ alt_identifier_name = name.to_s.split(Client::CommandBaseThor::ALT_IDENTIFIER_SEPARATOR)
228
+ instance.alt_identifier = alt_identifier_name.size > 1 ? alt_identifier_name.first : nil
229
+ return instance
230
+ end
231
+ end
232
+
233
+ class ActiveContext
234
+
235
+ # special case when we are not able to provide valid identifier but we are
236
+ # using it as such
237
+ NO_IDENTIFIER_PROVIDED = -1
238
+
239
+ # TODO: Remove accessor for debug purpose only
240
+ attr_accessor :context_list
241
+
242
+ def clone_me()
243
+ inst = ActiveContext.new
244
+ inst.context_list = @context_list.clone
245
+ return inst
246
+ end
247
+
248
+ def initialize
249
+ @context_list = []
250
+ end
251
+
252
+ def push_new_context(context_name, entity_name, context_value=nil)
253
+ @context_list << ContextEntity.create_context(context_name, entity_name, context_value)
254
+ end
255
+
256
+ def pop_context(n)
257
+ return @context_list.pop(n)
258
+ end
259
+
260
+ def find_identifier(entity_name)
261
+ results = @context_list.select { |e| (e.is_identifier? && (e.entity == entity_name.to_sym))}
262
+ return results.first
263
+ end
264
+
265
+ def find_command(entity_name)
266
+ results = @context_list.select { |e| (e.is_command? && (e.entity == entity_name.to_sym))}
267
+ return results.first
268
+ end
269
+
270
+ def name_list()
271
+ @context_list.collect { |e| e.is_alt_identifier? ? e.transform_alt_identifier_name : e.name }
272
+ end
273
+
274
+ def name_list_simple()
275
+ @context_list.collect { |e| e.name }
276
+ end
277
+
278
+
279
+ # returns list of entities that have identifier
280
+ def commands_that_have_identifiers()
281
+ filtered_entities = @context_list.select { |e| e.is_identifier? }
282
+ return filtered_entities.collect { |e| e.entity.to_s }
283
+ end
284
+
285
+ def command_list()
286
+ filtered_entities = @context_list.select { |e| e.is_command? }
287
+ return filtered_entities.collect { |e| e.entity.to_s }
288
+ end
289
+
290
+ # returns id to be used to retrive task list form the cache based on
291
+ # current active context
292
+ def get_task_cache_id()
293
+ identifier = command_list().join('_')
294
+ return 'dtk' if identifier.empty?
295
+ if current_alt_identifier?
296
+ return "#{identifier}_#{current_alt_identifier_name()}".to_sym()
297
+ end
298
+
299
+ return current_identifier? ? "#{identifier}_wid".to_sym : identifier.to_sym
300
+ end
301
+
302
+ def full_path()
303
+ path = name_list().join('/')
304
+ path = Context.enchance_path_with_alias(path, @context_list)
305
+
306
+ return "/#{path}"
307
+ end
308
+
309
+ def clear()
310
+ @context_list.clear
311
+ end
312
+
313
+ def empty?()
314
+ return @context_list.empty?
315
+ end
316
+
317
+ def is_n_context?
318
+ @context_list.size > 2
319
+ end
320
+
321
+ def current_command?
322
+ return @context_list.empty? ? true : @context_list.last.is_command?
323
+ end
324
+
325
+ def current_identifier?
326
+ return @context_list.empty? ? false : @context_list.last.is_identifier?
327
+ end
328
+
329
+ def current_alt_identifier?
330
+ return @context_list.empty? ? false : @context_list.last.is_alt_identifier?
331
+ end
332
+
333
+ def current_alt_identifier_name
334
+ @context_list.last.alt_identifier
335
+ end
336
+
337
+ def first_command_name()
338
+ @context_list.each do |e|
339
+ return e.name if e.is_command?
340
+ end
341
+
342
+ return nil
343
+ end
344
+
345
+ def is_there_identifier_for_first_context?
346
+ @context_list.each { |e| return true if e.is_identifier? }
347
+ return false
348
+ end
349
+
350
+ def last_command_name()
351
+ @context_list.reverse.each do |e|
352
+ return e.name if e.is_command?
353
+ end
354
+
355
+ return nil
356
+ end
357
+
358
+ def last_context_entity_name()
359
+ return @context_list.empty? ? nil : @context_list.last.entity
360
+ end
361
+
362
+ def last_context_name()
363
+ return @context_list.empty? ? nil : @context_list.last.name
364
+ end
365
+
366
+ def first_context_name()
367
+ return @context_list.empty? ? nil : @context_list.first.name
368
+ end
369
+
370
+ def first_context()
371
+ return @context_list.empty? ? nil : @context_list.first
372
+ end
373
+
374
+ def last_context()
375
+ return @context_list.empty? ? nil : @context_list.last
376
+ end
377
+
378
+ end
379
+
380
+ class CachedTasks < Hash
381
+ end
382
+
383
+ class OverrideTasks < Hash
384
+
385
+ attr_accessor :completed_tasks
386
+ attr_accessor :always_load_list
387
+
388
+
389
+ # help_item (Thor printable task), structure:
390
+ # [0] => task defintion
391
+ # [1] => task description
392
+ # [2] => task name
393
+
394
+ # overriden_task (DTK override task), structure:
395
+ # [0] => task name
396
+ # [1] => task defintion
397
+ # [2] => task description
398
+
399
+ # using 'always load listed' to skip adding task to completed tasks e.g load utils for workspace and workspace_node
400
+ def initialize(hash=nil, always_load_listed=[])
401
+ super(hash)
402
+ @completed_tasks = []
403
+ @always_load_list = always_load_listed
404
+ self.merge!(hash)
405
+ end
406
+
407
+ # returns true if there are overrides for tasks on first two levels.
408
+ def are_there_self_override_tasks?
409
+ return (self[:all][:self] || self[:command_only][:self] || self[:identifier_only][:self])
410
+ end
411
+
412
+ def check_help_item(help_item, is_command)
413
+ command_tasks, identifier_tasks = get_all_tasks(:self)
414
+ found = []
415
+
416
+ if is_command
417
+ found = command_tasks.select { |o_task| o_task[0].eql?(help_item[2]) }
418
+ else
419
+ found = identifier_tasks.select { |o_task| o_task[0].eql?(help_item[2]) }
420
+ end
421
+
422
+ # if we find self overriden task we remove it
423
+ # [found.first[1],found.first[2],found.first[0]] => we convert from o_task structure to thor help structure
424
+ return found.empty? ? help_item : [found.first[1],found.first[2],found.first[0]]
425
+ end
426
+
427
+ # returns 2 arrays one for commands and next one for identifiers
428
+ def get_all_tasks(child_name)
429
+ command_o_tasks, identifier_o_tasks = [], []
430
+ command_o_tasks = (self[:all][child_name]||[]) + (self[:command_only][child_name]||[])
431
+ identifier_o_tasks = (self[:all][child_name]||[]) + (self[:identifier_only][child_name]||[])
432
+ return command_o_tasks, identifier_o_tasks
433
+ end
434
+
435
+ def is_completed?(child_name)
436
+ # do not add task to completed if explicitly said to always load that task
437
+ return false if @always_load_list.include?(child_name)
438
+ @completed_tasks.include?(child_name)
439
+ end
440
+
441
+ def add_to_completed(child_name)
442
+ @completed_tasks << child_name
443
+ end
444
+ end
445
+
446
+ end
447
+ end
@@ -0,0 +1,27 @@
1
+ require 'hirb'
2
+
3
+ module DTK
4
+ module Shell
5
+
6
+ # We will use this class to generate header for console which would be always present,
7
+ # when activated. Hirb implementation will be used to display status information.
8
+
9
+ class HeaderShell
10
+
11
+ attr_accessor :active
12
+ alias_method :is_active?, :active
13
+
14
+ def initialize
15
+ @active = true
16
+ end
17
+
18
+ def print_header
19
+ puts "*********************"
20
+ puts "********************* #{Time.now} "
21
+ puts "*********************"
22
+ end
23
+
24
+
25
+ end
26
+ end
27
+ end