dtk-client 0.7.4.1 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/bin/dtk +10 -3
  3. data/bin/dtk-shell +1 -1
  4. data/lib/command_helpers/git_repo.rb +26 -20
  5. data/lib/command_helpers/jenkins_client.rb +4 -3
  6. data/lib/command_helpers/service_importer.rb +37 -25
  7. data/lib/commands.rb +2 -2
  8. data/lib/commands/common/thor/assembly_workspace.rb +185 -173
  9. data/lib/commands/common/thor/base_command_helper.rb +42 -0
  10. data/lib/commands/common/thor/clone.rb +1 -1
  11. data/lib/commands/common/thor/module.rb +37 -58
  12. data/lib/commands/common/thor/module/import.rb +1 -1
  13. data/lib/commands/common/thor/pull_from_remote.rb +7 -12
  14. data/lib/commands/common/thor/purge_clone.rb +1 -1
  15. data/lib/commands/common/thor/push_clone_changes.rb +3 -1
  16. data/lib/commands/common/thor/task_status.rb +52 -75
  17. data/lib/commands/common/thor/task_status/refresh_mode.rb +56 -0
  18. data/lib/commands/common/thor/task_status/snapshot_mode.rb +11 -0
  19. data/lib/commands/common/thor/task_status/stream_mode.rb +31 -0
  20. data/lib/commands/common/thor/task_status/stream_mode/element.rb +90 -0
  21. data/lib/commands/common/thor/task_status/stream_mode/element/no_results.rb +10 -0
  22. data/lib/commands/common/thor/task_status/stream_mode/element/render.rb +88 -0
  23. data/lib/commands/common/thor/task_status/stream_mode/element/stage.rb +13 -0
  24. data/lib/commands/common/thor/task_status/stream_mode/element/task_end.rb +10 -0
  25. data/lib/commands/common/thor/task_status/stream_mode/element/task_start.rb +10 -0
  26. data/lib/commands/thor/account.rb +10 -8
  27. data/lib/commands/thor/assembly.rb +9 -2
  28. data/lib/commands/thor/component_module.rb +0 -52
  29. data/lib/commands/thor/library.rb +1 -0
  30. data/lib/commands/thor/node.rb +1 -36
  31. data/lib/commands/thor/node_template.rb +4 -47
  32. data/lib/commands/thor/service.rb +57 -46
  33. data/lib/commands/thor/service_module.rb +2 -49
  34. data/lib/commands/thor/target.rb +7 -7
  35. data/lib/commands/thor/workspace.rb +44 -27
  36. data/lib/context_router.rb +4 -0
  37. data/lib/core.rb +71 -99
  38. data/lib/domain/response.rb +9 -0
  39. data/lib/domain/response/error_handler.rb +61 -0
  40. data/lib/dtk-client/version.rb +1 -1
  41. data/lib/dtk_client.rb +14 -0
  42. data/lib/dtk_error.rb +91 -0
  43. data/lib/error.rb +3 -9
  44. data/lib/execute/cli_pure/cli_rerouter.rb +82 -0
  45. data/lib/parser/adapters/thor.rb +3 -0
  46. data/lib/shell.rb +2 -1
  47. data/lib/shell/domain/context_params.rb +2 -0
  48. data/lib/util/console.rb +1 -1
  49. data/lib/util/os_util.rb +1 -0
  50. data/lib/util/remote_dependency_util.rb +20 -3
  51. data/lib/view_processor/table_print.rb +7 -25
  52. metadata +17 -5
  53. data/lib/commands/common/thor/test_action_agent.rb +0 -39
  54. data/lib/commands/thor/repo.rb +0 -35
@@ -7,6 +7,9 @@ module DTK
7
7
  module Client
8
8
  #TODO: should make higher level class be above whether it is 'rest'
9
9
  class Response < Common::Response
10
+ require File.expand_path('response/error_handler',File.dirname(__FILE__))
11
+ include ErrorHandlerMixin
12
+
10
13
  # :render_view => symbol specifing type of data to be rendered e.g. :assembly
11
14
  # :skip_render => flag that specifies that render is not needed (default: false)
12
15
  # :print_error_table => we use it if we want to print 'error legend' for given tables (default: false)
@@ -230,6 +233,12 @@ module DTK
230
233
  end
231
234
  end
232
235
 
236
+ class NotOk < self
237
+ def initialize(data={})
238
+ super(nil,{"data"=> data, "status" => "notok"})
239
+ end
240
+ end
241
+
233
242
  class Error < self
234
243
  include Common::Response::ErrorMixin
235
244
  def initialize(hash={})
@@ -0,0 +1,61 @@
1
+ module DTK; module Client
2
+ class Response
3
+ module ErrorHandlerMixin
4
+ # opts can be
5
+ # :default_error_if_nil - Boolean
6
+ def error_info?(opts={})
7
+ ErrorHandler.error_info?(self,opts)
8
+ end
9
+ end
10
+
11
+ module ErrorHandler
12
+ SpecificErrorCodes = [:unauthorized,:session_timeout,:broken,:forbidden,:timeout,:connection_refused,:resource_not_found,:pg_error]
13
+ DefaultErrorCode = :error
14
+ DefaultErrorMsg = 'Internal DTK Client error, please try again'
15
+
16
+ Info = Struct.new(:msg,:code,:backtrace)
17
+ def self.error_info?(response,opts={})
18
+ unless errors = response["errors"]
19
+ return (opts[:default_error_if_nil] && error_info_default())
20
+ end
21
+
22
+ error_msg = ""
23
+ error_internal = nil
24
+ error_backtrace = nil
25
+ error_code = nil
26
+ error_on_server = nil
27
+
28
+ #TODO: below just 'captures' first error
29
+ errors.each do |err|
30
+ error_msg += err["message"] unless err["message"].nil?
31
+ error_msg += err["error"] unless err["error"].nil?
32
+ error_on_server = true unless err["on_client"]
33
+ error_code = err["code"]||(err["errors"] && err["errors"].first["code"])
34
+ error_internal ||= (err["internal"] or error_code == "not_found") #"not_found" code is at Ramaze level; so error_internal not set
35
+ error_backtrace ||= err["backtrace"]
36
+ end
37
+
38
+ # normalize it for display
39
+ error_msg = error_msg.empty? ? DefaultErrorMsg : "#{error_msg}"
40
+
41
+ unless error_code and SpecificErrorCodes.include?(error_code)
42
+ error_code =
43
+ if error_internal
44
+ error_on_server ? :server_error : :client_error
45
+ else
46
+ DefaultErrorCode
47
+ end
48
+ end
49
+
50
+ error_code = error_code.to_sym
51
+ Info.new(error_msg,error_code,error_backtrace)
52
+ end
53
+
54
+ def self.error_info_default()
55
+ Info.new(DefaultErrorMsg,DefaultErrorCode,nil)
56
+ end
57
+
58
+ end
59
+ end
60
+ end; end
61
+
@@ -1,3 +1,3 @@
1
1
  module DtkClient
2
- VERSION="0.7.4.1"
2
+ VERSION="0.7.5"
3
3
  end
data/lib/dtk_client.rb ADDED
@@ -0,0 +1,14 @@
1
+ require File.expand_path('../client', __FILE__)
2
+ require File.expand_path('../configurator', __FILE__)
3
+ require File.expand_path('../parser/adapters/thor', __FILE__)
4
+ require File.expand_path('../shell/context', __FILE__)
5
+ require File.expand_path('../shell/domain/context_entity', __FILE__)
6
+ require File.expand_path('../shell/domain/active_context', __FILE__)
7
+ require File.expand_path('../shell/domain/context_params', __FILE__)
8
+ require File.expand_path('../shell/domain/override_tasks', __FILE__)
9
+ require File.expand_path('../shell/domain/shadow_entity', __FILE__)
10
+ require File.expand_path('../commands/thor/account', __FILE__)
11
+ require File.expand_path('../shell/parse_monkey_patch', __FILE__)
12
+ require File.expand_path('../shell/help_monkey_patch', __FILE__)
13
+ require File.expand_path('../execute/cli_pure/cli_rerouter', __FILE__)
14
+ require File.expand_path('../context_router', __FILE__)
data/lib/dtk_error.rb ADDED
@@ -0,0 +1,91 @@
1
+ module DTK
2
+ module Client
3
+ class DtkError < Error
4
+ def initialize(msg,opts={})
5
+ super(msg)
6
+ @backtrace = opts[:backtrace]
7
+ end
8
+ attr_reader :backtrace
9
+
10
+ def self.raise_error(response)
11
+ raise_if_error?(response,:default_error_if_nil => true)
12
+ end
13
+ def self.raise_if_error?(response,opts={})
14
+ # check for errors in response
15
+ unless error = response.error_info?(opts)
16
+ return
17
+ end
18
+
19
+ # if error_internal.first == true
20
+ case error.code
21
+ when :unauthorized
22
+ raise self, "[UNAUTHORIZED] Your session has been suspended, please log in again."
23
+ when :session_timeout
24
+ raise self, "[SESSION TIMEOUT] Your session has been suspended, please log in again."
25
+ when :broken
26
+ raise self, "[BROKEN] Unable to connect to the DTK server at host: #{Config[:server_host]}"
27
+ when :forbidden
28
+ raise DTK::Client::DtkLoginRequiredError, "[FORBIDDEN] Access not granted, please log in again."
29
+ when :timeout
30
+ raise self, "[TIMEOUT ERROR] Server is taking too long to respond."
31
+ when :connection_refused
32
+ raise self, "[CONNECTION REFUSED] Connection refused by server."
33
+ when :resource_not_found
34
+ raise self, "[RESOURCE NOT FOUND] #{error.msg}"
35
+ when :pg_error
36
+ raise self, "[PG_ERROR] #{error.msg}"
37
+ when :server_error
38
+ raise Server.new(error.msg,:backtrace => error.backtrace)
39
+ when :client_error
40
+ raise Client.new(error.msg,:backtrace => error.backtrace)
41
+ else
42
+ # if usage error occurred, display message to console and display that same message to log
43
+ raise Usage.new(error.msg)
44
+ end
45
+ end
46
+
47
+
48
+ class Usage < self
49
+ def initialize(error_msg,opts={})
50
+ msg_to_pass_to_super = "[ERROR] #{error_msg}"
51
+ super(msg_to_pass_to_super,opts)
52
+ end
53
+ end
54
+
55
+ class InternalError < self
56
+ def initialize(error_msg,opts={})
57
+ msg_to_pass_to_super = "[#{label(opts[:where])}] #{error_msg}"
58
+ super(msg_to_pass_to_super,opts)
59
+ end
60
+ def self.label(where=nil)
61
+ prefix = (where ? "#{where.to_s.upcase} " : '')
62
+ "#{prefix}#{InternalErrorLabel}"
63
+ end
64
+ InternalErrorLabel = 'INTERNAL ERROR'
65
+
66
+ private
67
+ def label(where=nil)
68
+ self.class.label(where)
69
+ end
70
+ end
71
+
72
+ class Client < InternalError
73
+ def initialize(error_msg,opts={})
74
+ super(error_msg,opts.merge(:where => :client))
75
+ end
76
+ def self.label(*args)
77
+ super(:client)
78
+ end
79
+ end
80
+ class Server < InternalError
81
+ def initialize(error_msg,opts={})
82
+ super(error_msg,opts.merge(:where => :server))
83
+ end
84
+ def self.label(*args)
85
+ super(:server)
86
+ end
87
+ end
88
+
89
+ end
90
+ end
91
+ end
data/lib/error.rb CHANGED
@@ -8,6 +8,9 @@ module DTK
8
8
  class Error < NameError
9
9
  end
10
10
 
11
+ # DtkError is child of Error; so order matters
12
+ require File.expand_path('dtk_error', File.dirname(__FILE__))
13
+
11
14
  class DSLParsing < Error
12
15
  def initialize(base_json_error,file_path=nil)
13
16
  super(err_msg(base_json_error,file_path))
@@ -48,15 +51,6 @@ module DTK
48
51
  class DtkImplementationError < Error
49
52
  end
50
53
 
51
- # we use this to log application errors
52
- class DtkError < Error
53
- def initialize(msg,opts={})
54
- super(msg)
55
- @backtrace = opts[:backtrace]
56
- end
57
- attr_reader :backtrace
58
- end
59
-
60
54
  class DtkLoginRequiredError < Error
61
55
  end
62
56
 
@@ -0,0 +1,82 @@
1
+ module DTK
2
+ class CLIRerouter
3
+
4
+ ROUTER_DATA = {
5
+ :service_module => [
6
+ { :regex => /service-module (?<service_module_id>[\w:\-]+) (?<method_name>stage) (?<assembly_id>[\w:\-]+) (?<instance_name>[\w:\-\.\:]+)/, :entity => 'assembly' },
7
+ { :regex => /service-module (?<service_module_id>[\w:\-]+) (?<method_name>deploy) (?<assembly_id>[\w:\-]+) (?<instance_name>[\w:\-\.\:]+)/ }
8
+ ],
9
+ :service => [
10
+ { :regex => /service (?<service_id>[\w:\-]+) (?<method_name>set-attribute) (?<name>[\w:\-\.\:]+) (?<value>[\w:\-\.\:]+)/ },
11
+ { :regex => /service (?<service_id>[\w:\-]+) (?<method_name>converge)/ },
12
+ { :regex => /service (?<method_name>delete-and-destroy) (?<instance_name>[\w:\-]+)/ }
13
+ ]
14
+ }
15
+
16
+ def initialize(entity_name, args)
17
+ @cli_string = CLIRerouter.formulate_command_string(entity_name, args)
18
+ @entity_name = CLIRerouter.norm(entity_name)
19
+
20
+ ROUTER_DATA[@entity_name].each do |defintion|
21
+ if match = @cli_string.match(defintion[:regex])
22
+ @method_name = CLIRerouter.norm(match[:method_name])
23
+
24
+ # sometimes we need to override entity
25
+ @entity_name = defintion[:entity] if defintion[:entity]
26
+
27
+ # we need to filter out IDs
28
+ @entity_ids = match.names.collect { |k| k.to_s.end_with?('_id') ? { k => match[k] } : nil }.compact
29
+
30
+ if @entity_ids.empty?
31
+ # match 1 is method name, there is no id
32
+ @args = match[2, match.size]
33
+ else
34
+ # match 1, 2 are id and method name rest are args
35
+ @args = match[@entity_ids.size + 2, match.size]
36
+ end
37
+
38
+ break
39
+ end
40
+ end
41
+
42
+ @conn = ::DTK::Client::Session.get_connection()
43
+ exit if validate_connection(@conn)
44
+ end
45
+
46
+ def run
47
+ new_context_params = DTK::Shell::ContextParams.new
48
+
49
+ @entity_ids.each do |value_hash|
50
+ key = value_hash.keys.first
51
+ value = value_hash.values.first
52
+ entity_name_of_param = key.gsub('_id', '')
53
+ new_context_params.add_context_name_to_params(entity_name_of_param, entity_name_of_param, value)
54
+ end
55
+
56
+ new_context_params.method_arguments = @args
57
+ new_context_params.pure_cli_mode = true
58
+ DTK::Client::ContextRouter.routeTask(@entity_name, @method_name, new_context_params, @conn)
59
+ end
60
+
61
+ def self.is_candidate?(entity_name, args)
62
+ cli = formulate_command_string(entity_name, args)
63
+ if definitions = ROUTER_DATA[norm(entity_name)]
64
+ is_match = definitions.find { |d| cli.match(d[:regex]) }
65
+
66
+ return true if is_match
67
+ end
68
+
69
+ return false
70
+ end
71
+
72
+ private
73
+
74
+ def self.norm(string_value)
75
+ return string_value ? string_value.gsub('-','_').to_sym : nil
76
+ end
77
+
78
+ def self.formulate_command_string(entity_name, args)
79
+ "#{entity_name} #{args.join(' ')}".strip()
80
+ end
81
+ end
82
+ end
@@ -329,6 +329,9 @@ module DTK
329
329
  unless response['data'].nil?
330
330
  identifiers = []
331
331
  response['data'].each do |element|
332
+ # special flag to filter out data not needed here
333
+ next if element['dtk_context_hidden']
334
+
332
335
  identifiers << { :name => element['display_name'], :identifier => element['id'], :shadow_entity => element['dtk_client_type'] }
333
336
  end
334
337
  return identifiers
data/lib/shell.rb CHANGED
@@ -60,7 +60,8 @@ def run_shell_command()
60
60
  #system('stty', stty_save) # Restore
61
61
  retry
62
62
  rescue Exception => e
63
- DtkLogger.instance.error_pp("[CLI INTERNAL ERROR] #{e.message}", e.backtrace)
63
+ client_internal_error = DTK::Client::DtkError::Client.label()
64
+ DtkLogger.instance.error_pp("[#{client_internal_error}] #{e.message}", e.backtrace)
64
65
  ensure
65
66
  puts "\n" unless e.is_a? DTK::Shell::ExitSignal
66
67
  # logout
@@ -3,11 +3,13 @@ module DTK::Shell
3
3
 
4
4
  attr_accessor :current_context
5
5
  attr_accessor :method_arguments
6
+ attr_accessor :pure_cli_mode
6
7
 
7
8
  def initialize(override_method_arguments = [])
8
9
  @current_context = ActiveContext.new
9
10
  @method_arguments = override_method_arguments
10
11
  @thor_options = Hash.new
12
+ @pure_cli_mode = false
11
13
 
12
14
  @method_arguments
13
15
  end
data/lib/util/console.rb CHANGED
@@ -39,7 +39,7 @@ module DTK::Client
39
39
  def confirmation_prompt_simple(message, add_options=true)
40
40
  # used to disable skip with ctrl+c
41
41
  trap("INT", "SIG_IGN")
42
- message += " (Y/n)" if add_options
42
+ message += " (y/n)" if add_options
43
43
 
44
44
  while line = Readline.readline("#{message}: ", true)
45
45
  if (line.eql?("yes") || line.eql?("y") || line.empty?)
data/lib/util/os_util.rb CHANGED
@@ -295,6 +295,7 @@ module DTK
295
295
  load File.expand_path('../../lib/domain/git_adapter.rb', File.dirname(__FILE__))
296
296
  load File.expand_path('../../lib/command_helpers/git_repo.rb', File.dirname(__FILE__))
297
297
  load File.expand_path('../../lib/command_helpers/service_importer.rb', File.dirname(__FILE__))
298
+ load File.expand_path('../../lib/view_processor/table_print.rb', File.dirname(__FILE__))
298
299
  paths = []
299
300
  paths << File.expand_path('../../lib/commands/thor/*.rb', File.dirname(__FILE__))
300
301
  paths << File.expand_path('../../lib/commands/common/thor/*.rb', File.dirname(__FILE__))
@@ -4,17 +4,19 @@
4
4
  module DTK
5
5
  module Client
6
6
  module RemoteDependencyUtil
7
-
8
7
  MODULE_REF_FILE = 'module_refs.yaml'
9
8
 
10
9
  class << self
11
-
12
- def print_dependency_warnings(response, success_msg=nil)
10
+ def print_dependency_warnings(response, success_msg = nil, opts = {})
13
11
  are_there_warnings = false
14
12
  return are_there_warnings if response.nil? || response.data.nil?
15
13
 
16
14
  warnings = response.data['dependency_warnings']
17
15
  if warnings && !warnings.empty?
16
+ if opts[:ignore_permission_warnings]
17
+ warnings.delete_if { |warning| warning['error_type'].eql?('no_permission') }
18
+ return if warnings.empty?
19
+ end
18
20
  print_out "Following warnings have been detected for current module by Repo Manager:\n"
19
21
  warnings.each { |w| print_out(" - #{w['message']}") }
20
22
  puts
@@ -24,6 +26,21 @@ module DTK
24
26
  are_there_warnings
25
27
  end
26
28
 
29
+ def check_permission_warnings(response)
30
+ errors = ''
31
+ dependency_warnings = response.data['dependency_warnings']
32
+
33
+ if dependency_warnings && !dependency_warnings.empty?
34
+ no_permissions = dependency_warnings.select { |warning| warning['error_type'].eql?('no_permission') }
35
+
36
+ errors << "\n\nYou do not have (R) permissions for modules:\n\n"
37
+ no_permissions.each { |np| errors << " - #{np['module_namespace']}:#{np['module_name']} (owner: #{np['module_owner']})\n" }
38
+ errors << "\nPlease contact owner(s) to change permissions for those modules."
39
+ end
40
+
41
+ raise DtkError, errors unless errors.empty?
42
+ end
43
+
27
44
  def module_ref_content(location)
28
45
  abs_location = File.join(location, MODULE_REF_FILE)
29
46
  File.exists?(abs_location) ? File.read(abs_location) : nil
@@ -21,6 +21,11 @@ class DtkOpenStruct < OpenStruct
21
21
  end
22
22
  end
23
23
 
24
+ # [Haris]
25
+ # Elements with action column (taks status) have been removed since they are no longer in use. In case of bug that is relying
26
+ # on existance of element and logic, please contact me to resolve it.
27
+ #
28
+
24
29
  module DTK
25
30
  module Client
26
31
  class ViewProcTablePrint < ViewProcessor
@@ -41,6 +46,7 @@ module DTK
41
46
 
42
47
  def initialize(data, data_type, forced_metadata, print_error_table)
43
48
  # if there is no custom metadata, then we use metadata predefined in meta-response.json file
49
+
44
50
  if forced_metadata.nil?
45
51
  # get all table definitions from json file
46
52
  @table_defintions = get_metadata()
@@ -84,7 +90,7 @@ module DTK
84
90
  evaluated_element = DtkOpenStruct.new
85
91
  error_element = DtkOpenStruct.new
86
92
 
87
- # based on mappign we set key = eval(value)
93
+ # based on mapping we set key = eval(value)
88
94
  table_defintion.each do |k,v|
89
95
  begin
90
96
  # due to problems with space we have special way of handling error columns
@@ -124,29 +130,6 @@ module DTK
124
130
  # add it with other
125
131
  @error_data << error_element
126
132
  end
127
- elsif k.include?('action')
128
- error_message = value_of(structured_element, v)
129
-
130
- # here we see if there was an error if not we will skip this
131
- # if so we add it to @error_data
132
-
133
- if error_message.empty?
134
- # no error message just add it as regular element
135
- evaluated_element.send("#{k}=",value_of(structured_element, v))
136
- else
137
- error_index = "[ #{value_of(structured_element,'logs.label')} ]" || ""
138
- error_type = value_of(structured_element,'logs.dtk_type') || ""
139
-
140
- # original table takes that index
141
- evaluated_element.send("#{k}=", error_index)
142
-
143
- # we set new error element
144
- error_element.id = error_index
145
- error_element.message = error_message
146
-
147
- # add it with other
148
- @action_data << error_element
149
- end
150
133
  else
151
134
  evaluated_element.send("#{k}=", value_of(structured_element, v))
152
135
  # eval "evaluated_element.#{k}=structured_element.#{v}"
@@ -161,7 +144,6 @@ module DTK
161
144
  end
162
145
  end
163
146
 
164
- @order_definition.delete('action')
165
147
  @order_definition.delete('errors')
166
148
 
167
149
  @evaluated_data << evaluated_element