dtk-client 0.5.9 → 0.5.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OGM2YzcyZjU0NTk3ZmY1MTUyYzJlZjQ3YmFkYzhjOGE5N2M4OTUxZQ==
4
+ ZDEyNmM1MGE3NzA2MzQ5OGMyMzhhNDVjZDUxY2JkMmE0MTYxNDFkYQ==
5
5
  data.tar.gz: !binary |-
6
- YWJlMTcxYzE0OGQwYWJlZjZjM2E4NTIxNGY5YTZmZjY1ZTk2ZjM0NQ==
6
+ MWRiODEwOTRkYjNkZDRhNzI4ZjNmNjVjZmQ3ODQwMmI1Y2VjMTQwNQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZWY1YmJlODNlOGEzYTU5ZGFiYzlhOTdmZDNlYTM0Y2QzNjllOTQyZDZkNjM0
10
- NGQ5ZDUxZDg2YjA0MmQ2NTUwNDNkNDkwNzFjZDc3NGYyZDgxMGRhZmQyY2Rh
11
- MTc4Yzc2OTJjZjRkYmM3ZjEyYzRlMjBiNGQzMGM3OTM3Njk5MGQ=
9
+ MjE1MzUwZTNlZTMzMWY3OTRkMWJhNGJmNDQyZjU2YTM2YjkwYWFhZjczZjRh
10
+ ODY2NTVjOTI5M2Y2YzVkYjFhMzlhMmYzMTcwZDZiZmNjZDNmM2VhZWIzZGY3
11
+ MzMyYzBlZDM3ZDQxNjVlOGQ4MjYzNmY3ZWEwMmE1OTIxYjkzNDY=
12
12
  data.tar.gz: !binary |-
13
- YjkxNDdhOGEwNzI0MWZhNGI4OWEzNjQ4YjM3ZWEzYzA2MWM3NGExM2Y1MGMw
14
- ZWE2ZDI1NWFjYjUzODI5MDBkMDZjMTA3Y2I2ZmYyMTNiOThhOTExZWMzY2Iz
15
- OTEwMWJkZDc0NDljYjY1ZDM1ZWU1MDk1ZjIwMjBkM2VmYjc0YTQ=
13
+ MzQwYzQ0YjhkOTRlNzkyZDJjZDQ1NzY1ZjMxYjc3ZGE5NmEyYTlmMjVmNTlj
14
+ NGU3NzMzMWE1ZGE5MTc0ZGMxNDY2MWQ4MTU0MjhkNjZlY2MzOWM3MjQyOWQx
15
+ MDYyNjMzNmI4MDlhZTkwYzIwNWQ0MWNmN2VmMzUwMWYzYzYwMDY=
data/bin/dtk CHANGED
@@ -24,7 +24,7 @@ $: << "/usr/lib/ruby/1.8/" #TODO: put in to get around path problem in rvm 1.9.2
24
24
 
25
25
 
26
26
  # check if .add_direct_access file exists, if not then add direct access and create .add_direct_access file
27
- check_direct_access(::DTK::Client::Configurator.check_direct_access)
27
+ resolve_direct_access(::DTK::Client::Configurator.check_direct_access)
28
28
  entries = []
29
29
 
30
30
  if ARGV.size > 0
data/bin/dtk-shell CHANGED
@@ -10,6 +10,6 @@ trap("INT", "SIG_IGN")
10
10
  ::DTK::Client::Configurator.create_missing_clone_dirs
11
11
 
12
12
  # check if .add_direct_access file exists, if not then add direct access and create .add_direct_access file
13
- check_direct_access(::DTK::Client::Configurator.check_direct_access)
13
+ resolve_direct_access(::DTK::Client::Configurator.check_direct_access)
14
14
 
15
15
  run_shell_command()
@@ -1,5 +1,6 @@
1
1
  require 'fileutils'
2
2
  dtk_require("../domain/git_adapter")
3
+ dtk_require("../domain/git_error_handler")
3
4
 
4
5
  module DTK; module Client; class CommandHelper
5
6
  class GitRepo < self; class << self
@@ -18,15 +19,15 @@ module DTK; module Client; class CommandHelper
18
19
  begin
19
20
  GitAdapter.clone(repo_url, target_repo_dir, opts[:branch])
20
21
  rescue => e
22
+ # Handling Git error messages with more user friendly messages
23
+ e = GitErrorHandler.handle(e)
24
+
21
25
  #cleanup by deleting directory
22
26
  FileUtils.rm_rf(target_repo_dir) if File.directory?(target_repo_dir)
23
27
  error_msg = "Clone to directory (#{target_repo_dir}) failed"
24
28
 
25
- # additional data about this exception
26
- if DTK::Configuration.get(:development_mode)
27
- DtkLogger.instance.error_pp(e.message, e.backtrace)
28
- end
29
-
29
+ DtkLogger.instance.error_pp(e.message, e.backtrace)
30
+
30
31
  raise ErrorUsage.new(error_msg,:log_error=>false)
31
32
  end
32
33
  {"module_directory" => target_repo_dir}
@@ -3,7 +3,7 @@ module DTK; module Client
3
3
  def self.update_ssh_known_hosts(server_dns,server_fingerprint)
4
4
  known_hosts_path = ssh_known_hosts_path()
5
5
  if File.file?(known_hosts_path)
6
- `ssh-keygen -f #{known_hosts_path} -R #{server_dns}`
6
+ `ssh-keygen -f #{known_hosts_path} -R #{server_dns} 2> /dev/null`
7
7
  File.open(known_hosts_path,"a"){|f|f << server_fingerprint}
8
8
  else
9
9
  ssh_base_dir = ssh_base_dir()
@@ -476,16 +476,22 @@ module DTK::Client
476
476
 
477
477
  def info_aux(context_params)
478
478
  assembly_or_workspace_id, node_id, component_id, attribute_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID, :node_id, :component_id, :attribute_id],method_argument_names)
479
+ is_json_return = context_params.get_forwarded_option(:json_return) || false
479
480
 
480
481
  post_body = {
481
482
  :assembly_id => assembly_or_workspace_id,
482
483
  :node_id => node_id,
483
484
  :component_id => component_id,
484
485
  :attribute_id => attribute_id,
485
- :subtype => :instance
486
+ :subtype => :instance,
487
+ :json_return => is_json_return
486
488
  }
487
489
 
488
490
  resp = post rest_url("assembly/info"), post_body
491
+
492
+ # if waiting for json response we do not need to render rest of data
493
+ return resp if is_json_return
494
+
489
495
  if (component_id.nil? && !node_id.nil?)
490
496
  resp.render_workspace_node_info("node")
491
497
  elsif (component_id && node_id)
@@ -715,6 +721,74 @@ module DTK::Client
715
721
  response.render_table(:netstat_data)
716
722
  end
717
723
 
724
+ def execute_tests_aux(context_params)
725
+ execute_test_tries = 6
726
+ execute_test_sleep = 0.5
727
+
728
+ assembly_or_workspace_id,node_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:node_id],method_argument_names)
729
+
730
+ #Get list of components on particular node
731
+ post_body = {
732
+ :assembly_id => assembly_or_workspace_id,
733
+ :node_id => node_id,
734
+ :subtype => "instance",
735
+ :about => "components"
736
+ }
737
+
738
+ response = post(rest_url("assembly/info_about"),post_body)
739
+
740
+ components = []
741
+
742
+ if !response['data'].nil?
743
+ response['data'].each do |c|
744
+ components << c['display_name']
745
+ end
746
+ end
747
+
748
+ post_body = {
749
+ :assembly_id => assembly_or_workspace_id,
750
+ :node_id => node_id,
751
+ :components => components
752
+ }
753
+
754
+ response = post(rest_url("assembly/initiate_execute_tests"),post_body)
755
+ return response unless response.ok?
756
+
757
+ action_results_id = response.data(:action_results_id)
758
+ end_loop, response, count, ret_only_if_complete = false, nil, 0, true
759
+
760
+ until end_loop do
761
+ post_body = {
762
+ :action_results_id => action_results_id,
763
+ :return_only_if_complete => ret_only_if_complete,
764
+ :disable_post_processing => false,
765
+ :sort_key => "module_name"
766
+ }
767
+ response = post(rest_url("assembly/get_action_results"),post_body)
768
+ count += 1
769
+ if count > execute_test_tries or response.data(:is_complete)
770
+ end_loop = true
771
+ else
772
+ #last time in loop return whetever is there
773
+ if count == execute_test_tries
774
+ ret_only_if_complete = false
775
+ end
776
+ sleep execute_test_sleep
777
+ end
778
+ end
779
+ filtered = response.data(:results)
780
+
781
+ #Filter out results per specific component
782
+ if !options["component"].nil?
783
+ filtered.reject! do |element|
784
+ element["component_name"] != options["component"]
785
+ end
786
+ end
787
+
788
+ response.set_data(*filtered)
789
+ response.render_table(:execute_tests_data)
790
+ end
791
+
718
792
  def get_ps_aux(context_params)
719
793
  get_ps_tries = 6
720
794
  get_ps_sleep = 0.5
@@ -10,14 +10,26 @@ module DTK::Client
10
10
  KEY_EXISTS_ALREADY_CONTENT = 'key exists already'
11
11
 
12
12
  no_tasks do
13
- def password_prompt(message, add_options=true)
13
+ def self.is_ssh_key_valid(path_to_key, rsa_pub_key)
14
+ unless path_to_key.include?(".pub")
15
+ raise DtkError, "[ERROR] Invalid public key file path (#{path_to_key}). Please provide valid path and try again."
16
+ end
17
+
18
+ if(rsa_pub_key.empty? || !rsa_pub_key.include?("AAAAB3NzaC1yc2EA"))
19
+ raise DtkError, "[ERROR] SSH public key (#{path_to_key}) does not have valid content. Please check your key and try again."
20
+ end
21
+ end
22
+
23
+ def password_prompt(message, add_options=true)
14
24
  begin
15
- while line = Readline.readline("#{message}: ", add_hist = false)
25
+ # while line = Readline.readline("#{message}: ", add_hist = false)
26
+ # using 'ask' from highline gem to be able to hide input for key and secret
27
+ while line = (HighLine.ask("#{message}") { |q| q.echo = false})
16
28
  raise Interrupt if line.empty?
17
29
  return line
18
30
  end
19
- rescue Interrupt => e
20
- retry
31
+ rescue Interrupt
32
+ return nil
21
33
  ensure
22
34
  puts "\n" if line.nil?
23
35
  end
@@ -35,17 +47,17 @@ module DTK::Client
35
47
  match, matched_username = nil, nil
36
48
 
37
49
  unless File.file?(path_to_key)
38
- OsUtil.put_warning "[ERROR] " ,"No ssh key file found at (#{path_to_key}). Path is wrong or it is necessary to generate the public rsa key (e.g., run `ssh-keygen -t rsa`)", :red
39
- abort
50
+ # OsUtil.put_warning "[ERROR] " ,"No ssh key file found at (#{path_to_key}). Path is wrong or it is necessary to generate the public rsa key (e.g., run `ssh-keygen -t rsa`)", :red
51
+ raise DtkError,"[ERROR] No ssh key file found at (#{path_to_key}). Path is wrong or it is necessary to generate the public rsa key (e.g., run `ssh-keygen -t rsa`)."
40
52
  end
41
53
 
42
54
  rsa_pub_key = File.open(path_to_key){|f|f.read}
55
+ is_ssh_key_valid(path_to_key, rsa_pub_key)
43
56
 
44
57
  post_body = { :rsa_pub_key => rsa_pub_key.chomp }
45
-
46
58
  post_body.merge!(:username => name.chomp) if name
47
- proper_response = nil
48
59
 
60
+ proper_response = nil
49
61
  response, key_exists_already = Account.internal_add_user_access("account/add_user_direct_access", post_body, 'service module')
50
62
 
51
63
  return response unless (response.ok? || key_exists_already)
@@ -56,7 +68,8 @@ module DTK::Client
56
68
  if response && !match
57
69
  repo_manager_fingerprint,repo_manager_dns = response.data_ret_and_remove!(:repo_manager_fingerprint,:repo_manager_dns)
58
70
  SshProcessing.update_ssh_known_hosts(repo_manager_dns,repo_manager_fingerprint)
59
- OsUtil.print("Ssh key added successfully!", :yellow)
71
+ name ||= response.data["new_username"]
72
+ OsUtil.print("SSH key '#{name}' added successfully!", :yellow)
60
73
  end
61
74
 
62
75
  return response, match, matched_username
@@ -75,16 +88,16 @@ module DTK::Client
75
88
  end
76
89
 
77
90
  3.times do
78
- old_pass_prompt = password_prompt("Enter old password")
91
+ old_pass_prompt = password_prompt("Enter old password: ")
79
92
 
80
93
  break if (old_pass.eql?(old_pass_prompt) || old_pass_prompt.nil?)
81
94
  OsUtil.print("Incorrect old password!", :yellow)
82
95
  end
83
96
  return unless old_pass.eql?(old_pass_prompt)
84
97
 
85
- new_pass_prompt = password_prompt("Enter new password")
98
+ new_pass_prompt = password_prompt("Enter new password: ")
86
99
  return if new_pass_prompt.nil?
87
- confirm_pass_prompt = password_prompt("Confirm new password")
100
+ confirm_pass_prompt = password_prompt("Confirm new password: ")
88
101
 
89
102
  if new_pass_prompt.eql?(confirm_pass_prompt)
90
103
  post_body = {:new_password => new_pass_prompt}
@@ -99,7 +112,7 @@ module DTK::Client
99
112
  end
100
113
  end
101
114
 
102
- desc "list-ssh-keys", "Show list of keys that your account profile has saved"
115
+ desc "list-ssh-keys", "Show list of key pairs that your account profile has saved"
103
116
  def list_ssh_keys(context_params)
104
117
  username = parse_key_value_file(::DTK::Client::Configurator.CRED_FILE)[:username]
105
118
  post_body = {:username => username}
@@ -108,7 +121,7 @@ module DTK::Client
108
121
  response.render_table(:account_ssh_keys)
109
122
  end
110
123
 
111
- desc "add-ssh-key NAME [PATH-TO-RSA-PUB-KEY]","Adds direct access to modules. Optional parameters is path to a ssh rsa public key and default is <user-home-dir>/.ssh/id_rsa.pub"
124
+ desc "add-ssh-key KEYPAIR-NAME [PATH-TO-RSA-PUB-KEY]","Adds a named ssh key to your user account to access modules from the catalog. Optional parameters is path to a ssh rsa public key and default is <user-home-dir>/.ssh/id_rsa.pub"
112
125
  def add_ssh_key(context_params)
113
126
  name, path_to_key = context_params.retrieve_arguments([:option_1!, :option_2],method_argument_names)
114
127
  path_to_key ||= SshProcessing.default_rsa_pub_key_path()
@@ -116,26 +129,25 @@ module DTK::Client
116
129
  response, matched, matched_username = Account.add_key(path_to_key, name)
117
130
 
118
131
  if matched
119
- DTK::Client::OsUtil.print("Provided SSH PUB key has already been added.", :yellow)
132
+ DTK::Client::OsUtil.print("Provided ssh pub key has already been added.", :yellow)
120
133
  elsif matched_username
121
134
  DTK::Client::OsUtil.print("User ('#{matched_username}') already exists.", :yellow)
122
135
  else
123
- FileUtils.touch(DTK::Client::Configurator::DIRECT_ACCESS) if response.ok?
136
+ DTK::Client::Configurator.add_current_user_to_direct_access() if response.ok?
124
137
  end
138
+
139
+ response
125
140
  end
126
141
 
127
- desc "remove-ssh-key NAME ","Removes user and direct access to modules."
128
- def remove_ssh_key(context_params)
142
+ desc "delete-ssh-key KEYPAIR-NAME ","Deletes the named ssh key from your user account"
143
+ def delete_ssh_key(context_params)
129
144
  name = context_params.retrieve_arguments([:option_1!],method_argument_names)
130
145
  post_body = {:username => name.chomp}
131
146
 
132
- response = post rest_url("component_module/remove_user_direct_access"), post_body
133
- return response unless response.ok?
134
-
135
- response = post rest_url("service_module/remove_user_direct_access"), post_body
147
+ response = post rest_url("account/remove_user_direct_access"), post_body
136
148
  return response unless response.ok?
137
149
 
138
- OsUtil.print("SSH key removed successfully!", :yellow)
150
+ OsUtil.print("Ssh key '#{name}' removed successfully!", :yellow)
139
151
  response
140
152
  end
141
153
 
@@ -356,7 +356,7 @@ TODO: might deprecate
356
356
  :desc => "DTK Repo Manager from which to resolve requested module."
357
357
  def install(context_params)
358
358
  create_missing_clone_dirs()
359
- check_direct_access(::DTK::Client::Configurator.check_direct_access)
359
+ resolve_direct_access(::DTK::Client::Configurator.check_direct_access)
360
360
  remote_module_name, version = context_params.retrieve_arguments([:option_1!, :option_2],method_argument_names)
361
361
  # in case of auto-import via service import, we skip cloning to speed up a process
362
362
  skip_cloning = context_params.get_forwarded_options()['skip_cloning'] if context_params.get_forwarded_options()
@@ -2,6 +2,9 @@ dtk_require_common_commands('thor/task_status')
2
2
  dtk_require_common_commands('thor/set_required_params')
3
3
  module DTK::Client
4
4
  class Node < CommandBaseThor
5
+
6
+ include AssemblyWorkspaceMixin
7
+
5
8
  no_tasks do
6
9
  include TaskStatusMixin
7
10
  include SetRequiredParamsMixin
@@ -73,15 +76,58 @@ module DTK::Client
73
76
 
74
77
  desc "NODE-NAME/ID info","Info about node"
75
78
  def info(context_params)
76
-
77
79
  node_id = context_params.retrieve_arguments([:node_id!],method_argument_names)
78
80
  post_body = {
79
81
  :node_id => node_id,
80
82
  :subtype => 'instance',
81
83
  }
84
+
82
85
  post rest_url("node/info"), post_body
83
86
  end
84
87
 
88
+ desc "NODE-NAME/ID ssh [--keypair] [--remote-user]","SSH into node, optional parameters are path to keypair and remote user."
89
+ method_option "--keypair",:type => :string, :desc => "Keypair used for connection, if not provided default is used", :banner => "KEYPAIR"
90
+ method_option "--remote-user",:type => :string, :desc => "Remote user used for connection", :banner => "REMOTE USER"
91
+ def ssh(context_params)
92
+ if OsUtil.is_windows?
93
+ puts "[NOTICE] SSH functionality is currenly not supported on Windows."
94
+ return
95
+ end
96
+
97
+ node_id = context_params.retrieve_arguments([:node_id!],method_argument_names)
98
+
99
+
100
+ keypair_location = options.keypair || OsUtil.dtk_keypair_location()
101
+
102
+
103
+ remote_user = options.send('remote-user') || 'ubuntu'
104
+
105
+ unless File.exists?(keypair_location||'')
106
+ error_message = keypair_location ? "Not able to find keypair, '#{keypair_location}'" : "Default keypair not set, please provide one in 'ssh' command"
107
+ raise ::DTK::Client::DtkError, error_message
108
+ end
109
+
110
+ context_params.forward_options({ :json_return => true })
111
+ response = info_aux(context_params)
112
+
113
+
114
+ if response.ok?
115
+ node_info = response.data['nodes'].find { |n| node_id == n['node_id'] }
116
+ public_dns = node_info ? node_info['external_ref']['ec2_public_address'] : nil
117
+
118
+ raise ::DTK::Client::DtkError, "Not able to resolve instance address, has instance been stopped?" unless public_dns
119
+
120
+ connection_string = "#{remote_user}@#{public_dns}"
121
+ ssh_command = "ssh -o \"StrictHostKeyChecking no\" -o \"UserKnownHostsFile /dev/null\" -i #{keypair_location} #{connection_string}"
122
+
123
+ OsUtil.print("You are entering SSH terminal (#{connection_string}) ...", :yellow)
124
+ Kernel.system(ssh_command)
125
+ OsUtil.print("You are leaving SSH terminal, and returning to DTK Shell ...", :yellow)
126
+ else
127
+ return response
128
+ end
129
+ end
130
+
85
131
  desc "NODE-NAME/ID list-components","List components that are on the node instance."
86
132
  method_option :list, :type => :boolean, :default => false
87
133
  def list_components(context_params)
@@ -140,6 +140,7 @@ TODO: overlaps with different meaning
140
140
  ['list-components',"list-components","# List components."]
141
141
  ],
142
142
  :utils => [
143
+ ['execute-tests',"execute-tests [--component COMPONENT-NAME]","# Execute tests. --component filters results per component."],
143
144
  ['get-netstats',"get-netstats","# Get netstats."],
144
145
  ['get-ps',"get-ps [--filter PATTERN]","# Get ps."],
145
146
  ['grep',"grep LOG-PATH NODE-ID-PATTERN GREP-PATTERN [--first]","# Grep log from multiple nodes. --first option returns first match (latest log entry)."],
@@ -156,7 +157,8 @@ TODO: overlaps with different meaning
156
157
  ['list-components',"list-components","# List components associated with service's node."],
157
158
  ['set-attribute',"set-attribute ATTRIBUTE-NAME [VALUE] [-u]","# (Un)Set attribute value. The option -u will unset the attribute's value."],
158
159
  ['start', "start", "# Start node instance."],
159
- ['stop', "stop", "# Stop node instance."]
160
+ ['stop', "stop", "# Stop node instance."],
161
+ ['ssh', "ssh [--keypair] [--remote-user]", "# SSH into node, optional parameters are path to keypair and remote user."]
160
162
  ],
161
163
  :component => [
162
164
  ['info',"info","# Return info about component instance belonging to given node."],
@@ -632,6 +634,13 @@ TODO: will put in dot release and will rename to 'extend'
632
634
  get_netstats_aux(context_params)
633
635
  end
634
636
 
637
+ # using HIDE_FROM_BASE to hide this command from base context (dtk:/assembly>)
638
+ desc "HIDE_FROM_BASE execute-tests [--component COMPONENT-NAME]", "Execute tests. --component filters results per component"
639
+ method_option :component, :type => :string, :desc => "Component name"
640
+ def execute_tests(context_params)
641
+ execute_tests_aux(context_params)
642
+ end
643
+
635
644
  # using HIDE_FROM_BASE to hide this command from base context (dtk:/assembly>)
636
645
  desc "HIDE_FROM_BASE get-ps [--filter PATTERN]", "Get ps"
637
646
  method_option :filter, :type => :boolean, :default => false, :aliases => '-f'
@@ -193,7 +193,7 @@ module DTK::Client
193
193
  method_option :ignore, :aliases => '-i', :type => :boolean, :default => false
194
194
  def install(context_params)
195
195
  create_missing_clone_dirs()
196
- check_direct_access(::DTK::Client::Configurator.check_direct_access)
196
+ resolve_direct_access(::DTK::Client::Configurator.check_direct_access)
197
197
  remote_module_name = context_params.retrieve_arguments([:option_1!],method_argument_names)
198
198
  ignore_component_error = options.ignore?
199
199
 
@@ -116,6 +116,7 @@ module DTK::Client
116
116
  ['list-components',"list-components","# List components."]
117
117
  ],
118
118
  :utils => [
119
+ ['execute-tests',"execute-tests [--component COMPONENT-NAME]","# Execute tests. --component filters results per component."],
119
120
  ['get-netstats',"get-netstats","# Get netstats."],
120
121
  ['get-ps',"get-ps [--filter PATTERN]","# Get ps."],
121
122
  ['grep',"grep LOG-PATH NODE-ID-PATTERN GREP-PATTERN [--first]","# Grep log from multiple nodes. --first option returns first match (latest log entry)."],
@@ -132,7 +133,8 @@ module DTK::Client
132
133
  ['list-components',"list-components","# List components associated with workspace's node."],
133
134
  ['set-attribute',"set-attribute ATTRIBUTE-NAME [VALUE] [-u]","# (Un)Set attribute value. The option -u will unset the attribute's value."],
134
135
  ['start', "start", "# Start node instance."],
135
- ['stop', "stop", "# Stop node instance."]
136
+ ['stop', "stop", "# Stop node instance."],
137
+ ['ssh', "ssh [--keypair] [--remote-user]", "# SSH into node, optional parameters are path to keypair and remote user."]
136
138
  ],
137
139
  :component => [
138
140
  ['info',"info","# Return info about component instance belonging to given node."],
@@ -311,6 +313,13 @@ module DTK::Client
311
313
  get_netstats_aux(context_params)
312
314
  end
313
315
 
316
+ # using HIDE_FROM_BASE to hide this command from base context (dtk:/workspace>)
317
+ desc "HIDE_FROM_BASE execute-tests [--component COMPONENT-NAME]", "Execute tests. --component filters results per component"
318
+ method_option :component, :type => :string, :desc => "Component name"
319
+ def execute_tests(context_params)
320
+ execute_tests_aux(context_params)
321
+ end
322
+
314
323
  # using HIDE_FROM_BASE to hide this command from base context (dtk:/workspace>)
315
324
  desc "HIDE_FROM_BASE get-ps [--filter PATTERN]", "Get ps"
316
325
  method_option :filter, :type => :boolean, :default => false, :aliases => '-f'
data/lib/configurator.rb CHANGED
@@ -6,12 +6,12 @@ module DTK
6
6
  module Client
7
7
  class Configurator
8
8
 
9
- CONFIG_FILE = File.join(OsUtil.dtk_local_folder, "client.conf")
9
+ CONFIG_FILE = File.join(OsUtil.dtk_local_folder, "client.conf")
10
10
  CRED_FILE = File.join(OsUtil.dtk_local_folder, ".connection")
11
11
  DIRECT_ACCESS = File.join(OsUtil.dtk_local_folder, ".add_direct_access")
12
12
 
13
- require 'fileutils'
14
- FileUtils.mkdir(OsUtil.dtk_local_folder) unless File.directory?(OsUtil.dtk_local_folder)
13
+ require 'fileutils'
14
+ FileUtils.mkdir(OsUtil.dtk_local_folder) unless File.directory?(OsUtil.dtk_local_folder)
15
15
 
16
16
  def self.CONFIG_FILE
17
17
  CONFIG_FILE
@@ -44,10 +44,10 @@ module DTK
44
44
 
45
45
  # return true/false, .add_direct_access file location and ssk key file location
46
46
  def self.check_direct_access
47
- file_exists = File.exists?(DIRECT_ACCESS)
47
+ username_exists = check_for_username_entry(client_username())
48
48
  ssh_key_path = SshProcessing.default_rsa_pub_key_path()
49
49
 
50
- {:file_exists => file_exists, :file_path => DIRECT_ACCESS, :ssh_key_path => ssh_key_path}
50
+ {:username_exists => username_exists, :file_path => DIRECT_ACCESS, :ssh_key_path => ssh_key_path}
51
51
  end
52
52
 
53
53
  def self.generate_conf_file(file_path, properties, header)
@@ -86,6 +86,53 @@ module DTK
86
86
  FileUtils.mkdir(OsUtil.module_clone_location) unless File.directory?(OsUtil.module_clone_location)
87
87
  FileUtils.mkdir(OsUtil.service_clone_location) unless File.directory?(OsUtil.service_clone_location)
88
88
  end
89
+
90
+
91
+ def self.parse_key_value_file(file)
92
+ #adapted from mcollective config
93
+ ret = Hash.new
94
+ raise DTK::Client::DtkError,"Config file (#{file}) does not exists" unless File.exists?(file)
95
+ File.open(file).each do |line|
96
+ # strip blank spaces, tabs etc off the end of all lines
97
+ line.gsub!(/\s*$/, "")
98
+ unless line =~ /^#|^$/
99
+ if (line =~ /(.+?)\s*=\s*(.+)/)
100
+ key = $1
101
+ val = $2
102
+ ret[key.to_sym] = val
103
+ end
104
+ end
105
+ end
106
+ ret
107
+ end
108
+ def self.add_current_user_to_direct_access()
109
+ username = client_username()
110
+
111
+ File.open(DIRECT_ACCESS, 'a') do |file|
112
+ file.puts(username)
113
+ end
114
+
115
+ true
116
+ end
117
+
118
+ def self.client_username()
119
+ parse_key_value_file(CRED_FILE)[:username]
120
+ end
121
+
122
+ #
123
+ # Method will check if there is username entry in DIRECT_ACCESS file
124
+ #
125
+ def self.check_for_username_entry(username)
126
+ if File.exists?(DIRECT_ACCESS)
127
+ File.open(DIRECT_ACCESS).each do |line|
128
+ if line.strip.eql?(username)
129
+ return true
130
+ end
131
+ end
132
+ end
133
+
134
+ return false
135
+ end
89
136
  end
90
137
  end
91
138
  end
data/lib/core.rb CHANGED
@@ -111,24 +111,25 @@ def validate_connection(connection)
111
111
  end
112
112
 
113
113
  # check if .add_direct_access file exists, if not then add direct access and create .add_direct_access file
114
- def check_direct_access(params)
115
- return if params[:file_exists]
114
+ def resolve_direct_access(params)
115
+ return if params[:username_exists]
116
116
 
117
117
  puts "Adding direct access for current user..."
118
118
  # response = DTK::Client::Account.add_access(params[:ssh_key_path])
119
119
  response, matched_pub_key, matched_username = DTK::Client::Account.add_key(params[:ssh_key_path])
120
120
 
121
121
  if !response.ok?
122
- DTK::Client::OsUtil.print("We were not able to add direct access for current user, server error '#{response.error_message}'. In order to properly use dtk-shell you will have to add access manually ('dtk account add-ssh-key').\n", :yellow)
122
+ DTK::Client::OsUtil.print("We were not able to add direct access for current user. #{response.error_message}. In order to properly use dtk-shell you will have to add access manually ('dtk account add-ssh-key').\n", :yellow)
123
123
  elsif matched_pub_key
124
124
  # message will be displayed by add key # TODO: Refactor this flow
125
125
  DTK::Client::OsUtil.print("Provided SSH PUB key has already been added.", :yellow)
126
- FileUtils.touch(params[:file_path])
126
+ DTK::Client::Configurator.add_current_user_to_direct_access()
127
127
  elsif matched_username
128
128
  DTK::Client::OsUtil.print("User with provided name already exists.", :yellow)
129
129
  else
130
- DTK::Client::OsUtil.print("Your SSH PUB key has been successfully added.", :yellow)
131
- FileUtils.touch(params[:file_path])
130
+ # commented out because 'add_key' method called above will also print the same message
131
+ # DTK::Client::OsUtil.print("Your SSH PUB key has been successfully added.", :yellow)
132
+ DTK::Client::Configurator.add_current_user_to_direct_access()
132
133
  end
133
134
 
134
135
 
@@ -218,22 +219,9 @@ module DTK
218
219
  module ParseFile
219
220
 
220
221
  def parse_key_value_file(file)
221
- #adapted from mcollective config
222
- ret = Hash.new
223
- raise DTK::Client::DtkError,"Config file (#{file}) does not exists" unless File.exists?(file)
224
- File.open(file).each do |line|
225
- # strip blank spaces, tabs etc off the end of all lines
226
- line.gsub!(/\s*$/, "")
227
- unless line =~ /^#|^$/
228
- if (line =~ /(.+?)\s*=\s*(.+)/)
229
- key = $1
230
- val = $2
231
- ret[key.to_sym] = val
232
- end
233
- end
234
- end
235
- ret
222
+ DTK::Client::Configurator.parse_key_value_file(file)
236
223
  end
224
+
237
225
  end
238
226
  class Config < Hash
239
227
  include Singleton
@@ -270,6 +258,7 @@ module DTK
270
258
  missing_keys = REQUIRED_KEYS - keys
271
259
  raise DTK::Client::DtkError,"Missing config keys (#{missing_keys.join(",")}). Please check your configuration file #{CONFIG_FILE} for required keys!" unless missing_keys.empty?
272
260
  end
261
+
273
262
  end
274
263
 
275
264
 
@@ -18,10 +18,13 @@ module DTK
18
18
  @git_repo.add(untracked())
19
19
  @git_repo.add(added())
20
20
  @git_repo.add(changed())
21
- deleted().each do |file, status|
22
- # this indicates that change has not been staged
23
- if status.stage
21
+ deleted().each do |file|
22
+ begin
24
23
  @git_repo.remove(file)
24
+ rescue
25
+ # ignore this error means file has already been staged
26
+ # we cannot support status of file, in 1.8.7 so this is
27
+ # solution for that
25
28
  end
26
29
  end
27
30
  end
@@ -0,0 +1,45 @@
1
+
2
+ module DTK
3
+ module Client
4
+
5
+ class GitHandledException < Exception
6
+ def initialize(msg, backtrace)
7
+ super(msg)
8
+ set_backtrace(backtrace)
9
+ end
10
+ end
11
+
12
+ class GitErrorHandler
13
+
14
+ # due to problems with git logging messages which are not user friendly we are going to wrap their error and try to produce more readable results
15
+ def self.handle(exception)
16
+ handled_exception = exception
17
+
18
+ if exception.is_a? Git::GitExecuteError
19
+ error_message = user_friendly_message(exception.message)
20
+ handled_exception = GitHandledException.new(error_message, exception.backtrace)
21
+ end
22
+
23
+ handled_exception
24
+ end
25
+
26
+ private
27
+
28
+ def self.user_friendly_message(message)
29
+ case message
30
+ when /repository not found/i
31
+ "Repository not found"
32
+ when /repository (.*) not found/i
33
+ "Repository #{$1.strip()} not found"
34
+ when /destination path (.*) already exists/i
35
+ "Destination folder #{$1.strip()} already exists"
36
+ when /Authentication failed for (.*)$/i
37
+ "Authentication failed for given repository #{$1.strip()}"
38
+ else
39
+ message
40
+ end
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -1,3 +1,3 @@
1
- module DtkClient
2
- VERSION="0.5.9"
3
- end
1
+ module DtkClient
2
+ VERSION="0.5.10"
3
+ end
data/lib/dtk_logger.rb CHANGED
@@ -61,14 +61,14 @@ class DtkLogger
61
61
  @logger.error(log_text) if log_created?
62
62
  end
63
63
 
64
- def error_pp(message, backtrace)
65
- error(message, true)
64
+ def error_pp(message, backtrace, sttdout_out = true)
65
+ error(message, sttdout_out)
66
66
  # we do not print this to STDOUT (will be overriden with DEVELOPMENT_MODE)
67
67
  error(PP.pp(backtrace, ""), false) if backtrace
68
68
  end
69
69
 
70
- def fatal_pp(message, backtrace)
71
- fatal(message, true)
70
+ def fatal_pp(message, backtrace, sttdout_out = true)
71
+ fatal(message, sttdout_out)
72
72
  # we do not print this to STDOUT (will be overriden with DEVELOPMENT_MODE)
73
73
  fatal(PP.pp(backtrace, ""), false) if backtrace
74
74
  end
@@ -25,8 +25,8 @@ module DTK
25
25
 
26
26
  @@cached_response = {}
27
27
  @@invalidate_map = []
28
- TIME_DIFF = 60 #second(s)
29
- EXTENDED_TIMEOUT = 360 #second(s)
28
+ TIME_DIFF = 60 # second(s)
29
+ EXTENDED_TIMEOUT = 360 # second(s)
30
30
  HIDE_FROM_BASE_CONTEXT = "HIDE_FROM_BASE"
31
31
 
32
32
  # thor command specific constants
@@ -289,40 +289,6 @@ module DTK
289
289
  end
290
290
  end
291
291
  end
292
-
293
- # will leave this commented for now until we check if new code works properly
294
- # if children
295
- # current_children = []
296
- # children.each do |child|
297
- # current_children << child.to_s
298
-
299
- # # create entry e.g. assembly_node_id
300
- # child_id_sym = (command.downcase + '_' + current_children.join('_') + '_wid').to_sym
301
-
302
- # # n-context matching
303
- # matched_data = task[1].usage.match(/\[?#{child.to_s.upcase}.?(NAME\/ID|ID\/NAME|ID|NAME)(\-?PATTERN)?\]?/)
304
- # if matched_data
305
- # cached_tasks[child_id_sym] = cached_tasks.fetch(child_id_sym,[]) << task_name
306
- # end
307
-
308
- # # override method list, we add these methods only once
309
- # if override_task_obj && !override_task_obj.is_completed?(child)
310
- # command_o_tasks, identifier_o_tasks = override_task_obj.get_all_tasks(child)
311
- # child_sym = (command.downcase + '_' + current_children.join('_')).to_sym
312
-
313
- # command_o_tasks.each do |o_task|
314
- # cached_tasks[child_sym] = cached_tasks.fetch(child_sym,[]) << o_task[0]
315
- # end
316
-
317
- # identifier_o_tasks.each do |o_task|
318
- # cached_tasks[child_id_sym] = cached_tasks.fetch(child_id_sym,[]) << o_task[0]
319
- # end
320
-
321
- # override_task_obj.add_to_completed(child)
322
- # end
323
- # end
324
- # end
325
-
326
292
  end
327
293
  end
328
294
 
@@ -482,6 +448,14 @@ module DTK
482
448
  return basename
483
449
  end
484
450
 
451
+ #
452
+ # Returns list of invisible contexts with sufix provided (if any)
453
+ #
454
+
455
+ def self.invisible_context_list(sufix = 'identifier')
456
+ self.respond_to?(:invisible_context) ? self.invisible_context.collect { |i| "#{i}-#{sufix}" } : []
457
+ end
458
+
485
459
  desc "help [SUBCOMMAND]", "Describes available subcommands or one specific subcommand"
486
460
  def help(*args)
487
461
  puts # pretty print
data/lib/shell/context.rb CHANGED
@@ -740,7 +740,7 @@ module DTK
740
740
  opts[id_label] = id
741
741
 
742
742
  response_ruby_obj = DTK::Client::CommandBaseThor.get_cached_response(endpoint.to_sym, url, opts)
743
- return [] unless response_ruby_obj.ok?
743
+ return [] if(response_ruby_obj.nil? || !response_ruby_obj.ok?)
744
744
 
745
745
  response_ruby_obj.data.each do |d|
746
746
  candidates << d["display_name"]
@@ -840,7 +840,7 @@ module DTK
840
840
  clazz = Context.get_command_class(entity_name)
841
841
  current_context_command = active_context_copy.last_command_name
842
842
 
843
- if (current_context_command != entity_name)
843
+ if ((current_context_command != entity_name) && !current_context_command.eql?("utils"))
844
844
  current_context_clazz = Context.get_command_class(current_context_command)
845
845
  options = Context.get_thor_options(current_context_clazz, cmd) unless current_context_command.nil?
846
846
  else
data/lib/shell/domain.rb CHANGED
@@ -24,6 +24,10 @@ module DTK
24
24
  @thor_options
25
25
  end
26
26
 
27
+ def get_forwarded_option(key)
28
+ @thor_options ? @thor_options[key] : nil
29
+ end
30
+
27
31
  def get_forwarded_thor_option(option_key)
28
32
  return @thor_options ? @thor_options[option_key] : nil
29
33
  end
@@ -79,6 +83,16 @@ module DTK
79
83
  id = matched[1].to_i - 1
80
84
  element = @method_arguments[id]
81
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
+
82
96
  unless method_info.empty?
83
97
  unless element
84
98
  errors << method_info[id] if required
@@ -215,6 +215,16 @@ class Thor
215
215
  # monkey patching here => END
216
216
  shell.print_table(list, :indent => 2, :truncate => true)
217
217
  shell.say
218
+
219
+ # print sub context information
220
+ # if @@shell_context && @@shell_context.active_context.current_identifier?
221
+ # sub_children = self.respond_to?(:valid_children) ? self.valid_children() : []
222
+ # sub_children += self.invisible_context_list()
223
+
224
+ # shell.say(" Change context (cc) to: #{sub_children.join(', ')}", :BOLD) unless sub_children.empty?
225
+ # shell.say
226
+ # end
227
+
218
228
  class_options_help(shell)
219
229
  end
220
230
  end
@@ -1,5 +1,6 @@
1
1
  require 'colorize'
2
2
  require 'readline'
3
+ require 'highline/import'
3
4
 
4
5
  module DTK
5
6
  module Shell
@@ -100,7 +101,9 @@ module DTK
100
101
  prompt_input = ">> "
101
102
  end
102
103
 
103
- while line = Readline.readline(prompt_input, true)
104
+ # while line = Readline.readline(prompt_input, true)
105
+ #using 'ask' from highline gem to be able to hide input for key and secret
106
+ while line = ask("#{prompt_input}") { |q| q.echo = false}
104
107
  if is_required && line.empty?
105
108
  puts INVALID_INPUT
106
109
  next
data/lib/util/os_util.rb CHANGED
@@ -9,6 +9,8 @@ module DTK
9
9
 
10
10
  extend Auxiliary
11
11
 
12
+ DTK_KEYPAIR = 'dtk.pem'
13
+
12
14
  class << self
13
15
  def is_mac?
14
16
  RUBY_PLATFORM.downcase.include?('darwin')
@@ -147,6 +149,18 @@ module DTK
147
149
  # remove last slash if set in configuration by mistake
148
150
  final_path.gsub(/\/$/,'')
149
151
  end
152
+
153
+ #
154
+ # Checks to find dtk.pem in configuration node, if not found displays tip message
155
+ #
156
+ def dtk_keypair_location()
157
+ path_to_keypair = "#{dtk_local_folder}#{DTK_KEYPAIR}"
158
+ return path_to_keypair if File.exists?(path_to_keypair)
159
+ print("TIP: You can save your keypair as '#{path_to_keypair}' and it will be used as default keypair.", :yellow)
160
+ nil
161
+ end
162
+
163
+
150
164
  private :clone_base_path
151
165
  #
152
166
  #
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.9
4
+ version: 0.5.10
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-03-06 00:00:00.000000000 Z
11
+ date: 2014-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -249,6 +249,7 @@ files:
249
249
  - lib/context_router.rb
250
250
  - lib/core.rb
251
251
  - lib/domain/git_adapter.rb
252
+ - lib/domain/git_error_handler.rb
252
253
  - lib/domain/response.rb
253
254
  - lib/dtk-client/version.rb
254
255
  - lib/dtk_constants.rb
@@ -325,7 +326,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
325
326
  version: '0'
326
327
  requirements: []
327
328
  rubyforge_project:
328
- rubygems_version: 2.1.9
329
+ rubygems_version: 2.1.5
329
330
  signing_key:
330
331
  specification_version: 4
331
332
  summary: DTK CLI client for DTK server interaction.