dtk-client 0.5.17 → 0.5.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +8 -8
  2. data/lib/command_helpers/git_repo.rb +82 -48
  3. data/lib/command_helpers/service_importer.rb +26 -17
  4. data/lib/command_helpers/test_module_creator.rb +6 -5
  5. data/lib/commands/common/thor/access_control.rb +5 -4
  6. data/lib/commands/common/thor/assembly_template.rb +75 -0
  7. data/lib/commands/common/thor/assembly_workspace.rb +86 -71
  8. data/lib/commands/common/thor/clone.rb +9 -7
  9. data/lib/commands/common/thor/common.rb +17 -10
  10. data/lib/commands/common/thor/edit.rb +65 -6
  11. data/lib/commands/common/thor/list_diffs.rb +4 -3
  12. data/lib/commands/common/thor/module.rb +86 -89
  13. data/lib/commands/common/thor/pull_clone_changes.rb +3 -2
  14. data/lib/commands/common/thor/pull_from_remote.rb +9 -5
  15. data/lib/commands/common/thor/purge_clone.rb +2 -2
  16. data/lib/commands/common/thor/push_clone_changes.rb +39 -16
  17. data/lib/commands/common/thor/push_to_remote.rb +3 -3
  18. data/lib/commands/thor/account.rb +16 -4
  19. data/lib/commands/thor/assembly.rb +66 -89
  20. data/lib/commands/thor/component_module.rb +40 -24
  21. data/lib/commands/thor/node.rb +7 -0
  22. data/lib/commands/thor/provider.rb +45 -23
  23. data/lib/commands/thor/service.rb +4 -7
  24. data/lib/commands/thor/service_module.rb +45 -20
  25. data/lib/commands/thor/test_module.rb +36 -22
  26. data/lib/commands/thor/workspace.rb +6 -6
  27. data/lib/core.rb +18 -17
  28. data/lib/domain/git_adapter.rb +30 -9
  29. data/lib/dtk-client/version.rb +1 -1
  30. data/lib/parser/adapters/thor.rb +47 -25
  31. data/lib/shell/context.rb +10 -2
  32. data/lib/shell.rb +18 -12
  33. data/lib/util/module_util.rb +41 -0
  34. data/lib/util/os_util.rb +25 -7
  35. metadata +4 -2
@@ -31,7 +31,7 @@ module DTK
31
31
 
32
32
  # thor command specific constants
33
33
  ALT_IDENTIFIER_SEPARATOR = ':::'
34
-
34
+
35
35
  def initialize(args, opts, config)
36
36
  @conn = config[:conn]
37
37
  super
@@ -41,7 +41,7 @@ module DTK
41
41
  @@shell_execution = shell_execution
42
42
 
43
43
  if method_name == 'help'
44
- ret = start([method_name] + context_params.method_arguments,:conn => conn)
44
+ ret = start([method_name] + context_params.method_arguments,:conn => conn)
45
45
  else
46
46
  ret = start([method_name, context_params] + (thor_options||[]),:conn => conn)
47
47
  end
@@ -103,15 +103,15 @@ module DTK
103
103
  subtype ||= {}
104
104
  current_ts = Time.now.to_i
105
105
  cache_id = (subtype.empty? ? :response : generate_cached_id(subtype))
106
-
106
+
107
107
  # if @@cache_response is empty return true if not than return time difference between
108
108
  # current_ts and ts stored in cache
109
- time_difference = @@cached_response[entity_name].nil? ? true : ((current_ts - @@cached_response[entity_name][:ts]) > TIME_DIFF)
109
+ time_difference = @@cached_response[entity_name].nil? ? true : ((current_ts - @@cached_response[entity_name][:ts]) > TIME_DIFF)
110
110
 
111
111
  if (@@cached_response[entity_name])
112
112
  time_difference = true if @@cached_response[entity_name][cache_id].nil?
113
113
  end
114
-
114
+
115
115
  if (time_difference || @@invalidate_map.include?(entity_name))
116
116
  response = post rest_url(url), subtype
117
117
 
@@ -149,8 +149,8 @@ module DTK
149
149
  # symbols don't have a <=> comparison operator in ruby 1.8.7
150
150
  subtype.map do |key,value|
151
151
  values += value.to_s
152
- end
153
-
152
+ end
153
+
154
154
  Digest::SHA1.hexdigest(values)
155
155
  end
156
156
 
@@ -232,7 +232,7 @@ module DTK
232
232
  alternate_identifiers.each do |a_provider|
233
233
  if matched_alt_identifiers_data = task[1].usage.match(/\[?#{a_provider}.?(NAME\/ID|ID\/NAME)\]?/)
234
234
  command_alt_sym = "#{command}_#{a_provider}".downcase.to_sym
235
- cached_tasks[command_alt_sym] = cached_tasks.fetch(command_alt_sym,[])
235
+ cached_tasks[command_alt_sym] = cached_tasks.fetch(command_alt_sym,[])
236
236
  cached_tasks[command_alt_sym] << task_name
237
237
  # when found break
238
238
  break
@@ -254,7 +254,7 @@ module DTK
254
254
  # if there are '[' it means it is optinal identifiers so it is tier 1 and tier 2 task
255
255
  cached_tasks[command_sym] << task_name if matched_data[0].include?('[')
256
256
  end
257
-
257
+
258
258
  # n-level matching
259
259
  all_children.each do |child|
260
260
  current_children = []
@@ -268,7 +268,7 @@ module DTK
268
268
  # n-context matching
269
269
  matched_data = task[1].usage.match(/^\[?#{c.to_s.upcase}.?(NAME\/ID|ID\/NAME|ID|NAME)(\-?PATTERN)?\]?/)
270
270
  if matched_data
271
- cached_tasks[child_id_sym] = cached_tasks.fetch(child_id_sym,[]) << task_name
271
+ cached_tasks[child_id_sym] = cached_tasks.fetch(child_id_sym,[]) << task_name
272
272
  end
273
273
 
274
274
  # override method list, we add these methods only once
@@ -290,7 +290,7 @@ module DTK
290
290
  end
291
291
  end
292
292
  end
293
-
293
+
294
294
  # there is always help, and in all cases this is exception to the rule
295
295
  cached_tasks[command_id_sym] << 'help'
296
296
 
@@ -303,18 +303,18 @@ module DTK
303
303
 
304
304
  context_list = self.get_identifiers(conn, context_params)
305
305
  results = context_list.select { |e| e[:name].eql?(value) || e[:identifier].eql?(value.to_i)}
306
-
306
+
307
307
  return results.empty? ? nil : results.first
308
308
  end
309
309
 
310
310
  def self.get_identifiers(conn, context_params)
311
311
  @conn = conn if @conn.nil?
312
-
312
+
313
313
  # we force raw output
314
314
  # options = Thor::CoreExt::HashWithIndifferentAccess.new({'list' => true})
315
315
 
316
316
  3.downto(1) do
317
- # get list data from one of the methods
317
+ # get list data from one of the methods
318
318
  if respond_to?(:validation_list)
319
319
  response = validation_list(context_params)
320
320
  else
@@ -324,12 +324,12 @@ module DTK
324
324
 
325
325
  unless (response.nil? || response.empty?)
326
326
  unless response['data'].nil?
327
- identifiers = []
327
+ identifiers = []
328
328
  response['data'].each do |element|
329
329
  identifiers << { :name => element['display_name'], :identifier => element['id'] }
330
330
  end
331
331
  return identifiers
332
- end
332
+ end
333
333
  end
334
334
  unless response.nil?
335
335
  break if response["status"].eql?('ok')
@@ -343,6 +343,14 @@ module DTK
343
343
 
344
344
  no_tasks do
345
345
 
346
+ #
347
+ # Run shell command directly from main, use with CAUTION
348
+ #
349
+
350
+ def run_shell_command(line)
351
+ TOPLEVEL_BINDING.eval('self').execute_shell_command_internal(line)
352
+ end
353
+
346
354
  ##
347
355
  # Block that allows users to specify part of the code which is expected to run for longer duration
348
356
  #
@@ -379,7 +387,7 @@ module DTK
379
387
  name, usage = current_method_info
380
388
  results = usage.split(name.gsub(/_/,'-')).last || ""
381
389
  return results.split(' ')
382
- end
390
+ end
383
391
 
384
392
  #TODO: can make more efficient by having rest call that returns name from id, rather than using 'list path'
385
393
  #entity_id can be a name as well as an id
@@ -397,12 +405,12 @@ module DTK
397
405
  match = response['data'].find{|entity|entity_id == entity['id']}
398
406
  end
399
407
  unless match
400
- raise DTK::Client::DtkError, "Not able to resolve entity name, please provide #{entity_type} name."
408
+ raise DTK::Client::DtkError, "Not able to resolve entity name, please provide #{entity_type} name."
401
409
  end
402
410
  match['display_name']
403
411
  end
404
412
 
405
- def is_numeric_id?(possible_id)
413
+ def is_numeric_id?(possible_id)
406
414
  !possible_id.to_s.match(/^[0-9]+$/).nil?
407
415
  end
408
416
 
@@ -414,9 +422,9 @@ module DTK
414
422
  trap("INT", false)
415
423
  return line
416
424
  end
417
- end
425
+ end
418
426
  end
419
-
427
+
420
428
  def get_type_and_raise_error_if_invalid(about, default_about, type_options)
421
429
  about ||= default_about
422
430
  raise DTK::Client::DtkError, "Not supported type '#{about}' for list for current context level. Possible type options: #{type_options.join(', ')}" unless type_options.include?(about)
@@ -425,8 +433,22 @@ module DTK
425
433
 
426
434
  # check for delimiter '/', if present returns namespace and name for module/service
427
435
  # returns: namespace, name
428
- def get_namespace_and_name(input_remote_name)
429
- (input_remote_name||'').include?('/') ? input_remote_name.split('/') : [nil, input_remote_name]
436
+ def get_namespace_and_name(input_remote_name, delimiter)
437
+ (input_remote_name||'').include?(delimiter) ? input_remote_name.split(delimiter) : [nil, input_remote_name]
438
+ end
439
+
440
+ def get_namespace_and_name_for_component(component_full_name)
441
+ namespace, name = nil, ''
442
+
443
+ if (component_full_name||'').include?(':')
444
+ match = component_full_name.match(/(\w*\-?\w*):{1}(.*)/)
445
+ namespace, name = [$1,$2]
446
+
447
+ return [nil, component_full_name] if (name.include?(':') && !name.include?('::'))
448
+ component_full_name = name
449
+ end
450
+
451
+ [namespace, component_full_name]
430
452
  end
431
453
  end
432
454
 
@@ -448,7 +470,7 @@ module DTK
448
470
  end
449
471
 
450
472
  #
451
- # Returns list of invisible contexts with sufix provided (if any)
473
+ # Returns list of invisible contexts with sufix provided (if any)
452
474
  #
453
475
 
454
476
  def self.invisible_context_list(sufix = 'identifier')
@@ -459,7 +481,7 @@ module DTK
459
481
  def help(*args)
460
482
  puts # pretty print
461
483
  not_dtk_clazz = true
462
-
484
+
463
485
  if defined?(DTK::Client::Dtk)
464
486
  not_dtk_clazz = !self.class.eql?(DTK::Client::Dtk)
465
487
  end
data/lib/shell/context.rb CHANGED
@@ -748,13 +748,21 @@ module DTK
748
748
  def load_extended_context_commands(extended_context_commands, active_context_copy)
749
749
  candidates = []
750
750
  entity_name = active_context_copy.last_context
751
+ parent_entity = active_context_copy.context_list[1]
751
752
 
752
753
  if entity_name.is_identifier?
753
754
  endpoint = extended_context_commands[:endpoint]
754
755
  url = extended_context_commands[:url]
755
756
  opts = extended_context_commands[:opts]||{}
756
757
 
757
- id_label = "#{endpoint}_id".to_sym
758
+ if (parent_entity && parent_entity.is_identifier? && (parent_entity != entity_name))
759
+ parent_id_label = "#{endpoint}_id".to_sym
760
+ parent_id = parent_entity.identifier
761
+ opts[parent_id_label] = parent_id
762
+ id_label = "#{entity_name.entity}_id".to_sym
763
+ end
764
+
765
+ id_label ||= "#{endpoint}_id".to_sym
758
766
  id = entity_name.identifier
759
767
  opts[id_label] = id
760
768
 
@@ -968,7 +976,7 @@ module DTK
968
976
  private
969
977
 
970
978
  # list of commands that should be excluded from history
971
- EXCLUDE_COMMAND_LIST = ['create-provider']
979
+ EXCLUDE_COMMAND_LIST = ['create-provider','create-ec2-provider','create-physical-provider']
972
980
 
973
981
  def self.is_allowed_command?(full_command_entry)
974
982
  found = EXCLUDE_COMMAND_LIST.find { |cmd| full_command_entry.include?(cmd) }
data/lib/shell.rb CHANGED
@@ -17,7 +17,7 @@ require 'thor'
17
17
  $shell_mode = true
18
18
 
19
19
  ALIAS_COMMANDS = {
20
- 'ls' => 'list',
20
+ 'ls' => 'list',
21
21
  'cd' => 'cc',
22
22
  'rm' => 'delete'
23
23
  }
@@ -45,7 +45,7 @@ def run_shell_command()
45
45
  puts "\n"
46
46
  raise Interrupt
47
47
  }
48
-
48
+
49
49
  # runtime part
50
50
  begin
51
51
  while line = Readline.readline(prompt, true)
@@ -75,7 +75,7 @@ def init_shell_context()
75
75
  begin
76
76
  @context = DTK::Shell::Context.new
77
77
  @shell_header = DTK::Shell::HeaderShell.new
78
- # loads root context
78
+ # loads root context
79
79
  @context.load_context()
80
80
 
81
81
  @t1 = nil
@@ -121,10 +121,10 @@ def execute_shell_command(line, prompt)
121
121
  end
122
122
  end
123
123
 
124
-
124
+
125
125
  if ('cc' == cmd)
126
126
  # in case there is no params we just reload command
127
- args << "/" if args.empty?
127
+ args << "/" if args.empty?
128
128
  prompt = @context.change_context(args, cmd)
129
129
  elsif ('popc' == cmd)
130
130
  @context.dirs.shift()
@@ -149,9 +149,9 @@ def execute_shell_command(line, prompt)
149
149
 
150
150
  # get all next-context-candidates (e.g. for assembly get all assembly_names)
151
151
  context_candidates = @context.get_ac_candidates_for_context(@context.active_context.last_context(), @context.active_context())
152
-
152
+
153
153
  # this part of the code is used for calling of nested commands from base context (dtk:/>assembly/assembly_id converge)
154
- # base_command is used to check if first command from n-level is valid e.g.
154
+ # base_command is used to check if first command from n-level is valid e.g.
155
155
  # (dtk:/>assembly/assembly_id converge - chech if 'assembly' exists in context_candidates)
156
156
  # revert_context is used to return to context which command is called from after command is executed
157
157
  base_command = cmd.split('/').first
@@ -165,12 +165,12 @@ def execute_shell_command(line, prompt)
165
165
 
166
166
  if cmd.nil?
167
167
  prompt = @context.change_context(["-"]) if revert_context
168
- raise DTK::Client::DtkValidationError, "You have to provide command after context name. Usage: CONTEXT-TYPE/CONTEXT-NAME COMMAND [ARG1] .. [ARG2]."
168
+ raise DTK::Client::DtkValidationError, "You have to provide command after context name. Usage: CONTEXT-TYPE/CONTEXT-NAME COMMAND [ARG1] .. [ARG2]."
169
169
  end
170
170
 
171
171
  # send monkey patch class information about context
172
172
  Thor.set_context(@context)
173
-
173
+
174
174
  # we get command and hash params, will return Validation error if command is not valid
175
175
  entity_name, method_name, context_params, thor_options, invalid_options = @context.get_command_parameters(cmd,args)
176
176
 
@@ -178,7 +178,7 @@ def execute_shell_command(line, prompt)
178
178
  if context_candidates.include?(method_name)
179
179
  context_params.add_context_to_params(method_name, entity_name, method_name)
180
180
  method_name = context_params.method_arguments.shift if context_params.method_arguments.size > 0
181
- else
181
+ else
182
182
  unless @context.method_valid?(method_name)
183
183
  prompt = @context.change_context(["-"]) if revert_context
184
184
  raise DTK::Client::DtkValidationError, "Method '#{method_name}' is not valid in current context."
@@ -194,7 +194,7 @@ def execute_shell_command(line, prompt)
194
194
  # when 'delete' or 'delete-and-destroy' command is executed reload cached tasks with latest commands
195
195
  unless (args.nil? || args.empty?)
196
196
  @context.reload_cached_tasks(entity_name) if (method_name.include?('delete') || method_name.include?('import'))
197
- end
197
+ end
198
198
 
199
199
  # check execution status, prints status to sttout
200
200
  DTK::Shell::StatusMonitor.check_status()
@@ -210,10 +210,16 @@ def execute_shell_command(line, prompt)
210
210
  rescue DTK::Shell::Error => e
211
211
  DtkLogger.instance.error(e.message, true)
212
212
  end
213
-
213
+
214
214
  return prompt
215
215
  end
216
216
 
217
+ public
218
+
219
+ def execute_shell_command_internal(line)
220
+ execute_shell_command(line, DTK::Shell::Context::DTK_ROOT_PROMPT)
221
+ end
222
+
217
223
 
218
224
 
219
225
 
@@ -0,0 +1,41 @@
1
+ module DTK
2
+ module Client
3
+ module ModuleUtil
4
+
5
+ NAMESPACE_SEPERATOR = ':'
6
+
7
+ def self.resolve_name(module_name, module_namespace)
8
+ is_invalid = module_name.nil? || module_namespace.nil? || module_name.empty? || module_namespace.empty?
9
+ raise DtkError, "Failed to provide module name (#{module_name}) or namespace (#{module_namespace})" if is_invalid
10
+ "#{module_namespace}#{NAMESPACE_SEPERATOR}#{module_name}"
11
+ end
12
+
13
+ def self.join_name(module_name, module_namespace)
14
+ module_namespace ? resolve_name(module_name, module_namespace) : module_name
15
+ end
16
+
17
+ # returns [namespace,name]; namespace can be null if cant determine it
18
+ def self.full_module_name_parts?(name_or_full_module_name)
19
+ if name_or_full_module_name.nil?
20
+ return [nil,nil]
21
+ end
22
+ if name_or_full_module_name =~ Regexp.new("(^.+)#{NAMESPACE_SEPERATOR}(.+$)")
23
+ namespace,name = [$1,$2]
24
+ else
25
+ namespace,name = [nil,name_or_full_module_name]
26
+ end
27
+ [namespace,name]
28
+ end
29
+
30
+ def self.filter_module_name(name_or_full_module_name)
31
+ full_module_name_parts?(name_or_full_module_name).last
32
+ end
33
+
34
+ def self.check_format!(module_identifier)
35
+ return module_identifier if module_identifier.match(/^[0-9]+$/)
36
+ DtkLogger.instance.debug(caller)
37
+ raise DtkError, "Module name should be in following format NAMESPACE#{NAMESPACE_SEPERATOR}MODULE_NAME" unless module_identifier.match(Regexp.new("^.+#{NAMESPACE_SEPERATOR}.+$"))
38
+ end
39
+ end
40
+ end
41
+ end
data/lib/util/os_util.rb CHANGED
@@ -100,7 +100,8 @@ module DTK
100
100
 
101
101
  def module_location(module_type,module_name,version=nil,opts={})
102
102
  # compact used because module_name can be nil
103
- module_location_parts(module_type,module_name,version,opts).compact.join('/')
103
+ location = module_location_parts(module_type,module_name,version,opts).compact.join('/')
104
+ location
104
105
  end
105
106
 
106
107
  # if module location is /a/b/d/mod it returns ['/a/b/d','mod']
@@ -116,7 +117,12 @@ module DTK
116
117
  ["#{base_all_types}/#{type}", module_name]
117
118
  end
118
119
  else
119
- [base_path, "#{module_name}#{version && "-#{version}"}"]
120
+ # we detect if we are using full name
121
+ if (module_name.match(/(.*)#{ModuleUtil::NAMESPACE_SEPERATOR}(.*)/))
122
+ [base_path, "#{$1}", "#{$2}#{version && "-#{version}"}"]
123
+ else
124
+ [base_path, "#{module_name}#{version && "-#{version}"}"]
125
+ end
120
126
  end
121
127
  end
122
128
 
@@ -127,7 +133,7 @@ module DTK
127
133
  end
128
134
 
129
135
  def module_clone_location(module_type)
130
- case module_type
136
+ case module_type.to_s
131
137
  when "component_module"
132
138
  return component_clone_location
133
139
  when "service_module"
@@ -135,7 +141,7 @@ module DTK
135
141
  when "test_module"
136
142
  test_clone_location
137
143
  else
138
- raise Client::DtkError, "Unexpected module_type (#{module_type})"
144
+ raise Client::DtkError, "Unexpected module_type (#{module_type}) when determining module location"
139
145
  end
140
146
  end
141
147
 
@@ -158,12 +164,12 @@ module DTK
158
164
  def clone_base_path(module_type)
159
165
 
160
166
  path =
161
- case module_type
167
+ case module_type.to_sym
162
168
  when :service_module then Config[:service_location]
163
169
  when :component_module then Config[:module_location]
164
170
  when :test_module then Config[:test_module_location]
165
171
  when :assembly_module then Config[:assembly_module_base_location]
166
- else raise Client::DtkError, "Unexpected module_type (#{module_type})"
172
+ else raise Client::DtkError, "Unexpected module_type (#{module_type}) when determining base path"
167
173
  end
168
174
 
169
175
 
@@ -189,7 +195,19 @@ module DTK
189
195
  #
190
196
  def local_component_module_list()
191
197
  component_module_dir = component_clone_location()
192
- Dir.entries(component_module_dir).select {|entry| File.directory? File.join(component_module_dir,entry) and !(entry =='.' || entry == '..') }
198
+
199
+ directories = Dir.entries(component_module_dir).map do |entry|
200
+ next if (entry =='.' || entry == '..' || entry.index('.') == 0)
201
+
202
+ Dir.entries("#{component_module_dir}/#{entry}").map do |m_entry|
203
+ next unless File.directory? File.join(component_module_dir,entry,m_entry)
204
+ next if (m_entry =='.' || m_entry == '..' || m_entry.index('.') == 0)
205
+
206
+ ModuleUtil.join_name(m_entry, entry)
207
+ end
208
+ end
209
+
210
+ directories.flatten.select { |d| !d.nil? }
193
211
  end
194
212
 
195
213
  # Public method will convert given string, to string with colorize output
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dtk-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.17
4
+ version: 0.5.18
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rich PELAVIN
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-14 00:00:00.000000000 Z
11
+ date: 2014-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -210,6 +210,7 @@ files:
210
210
  - lib/commands.rb
211
211
  - lib/commands/common/thor/access_control.rb
212
212
  - lib/commands/common/thor/action_result_handler.rb
213
+ - lib/commands/common/thor/assembly_template.rb
213
214
  - lib/commands/common/thor/assembly_workspace.rb
214
215
  - lib/commands/common/thor/clone.rb
215
216
  - lib/commands/common/thor/common.rb
@@ -282,6 +283,7 @@ files:
282
283
  - lib/util/common_util.rb
283
284
  - lib/util/console.rb
284
285
  - lib/util/dtk_puppet.rb
286
+ - lib/util/module_util.rb
285
287
  - lib/util/os_util.rb
286
288
  - lib/util/permission_util.rb
287
289
  - lib/util/remote_dependency_util.rb