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 +8 -8
- data/bin/dtk +1 -1
- data/bin/dtk-shell +1 -1
- data/lib/command_helpers/git_repo.rb +6 -5
- data/lib/command_helpers/ssh_processing.rb +1 -1
- data/lib/commands/common/thor/assembly_workspace.rb +75 -1
- data/lib/commands/thor/account.rb +35 -23
- data/lib/commands/thor/component_module.rb +1 -1
- data/lib/commands/thor/node.rb +47 -1
- data/lib/commands/thor/service.rb +10 -1
- data/lib/commands/thor/service_module.rb +1 -1
- data/lib/commands/thor/workspace.rb +10 -1
- data/lib/configurator.rb +52 -5
- data/lib/core.rb +10 -21
- data/lib/domain/git_adapter.rb +6 -3
- data/lib/domain/git_error_handler.rb +45 -0
- data/lib/dtk-client/version.rb +3 -3
- data/lib/dtk_logger.rb +4 -4
- data/lib/parser/adapters/thor.rb +10 -36
- data/lib/shell/context.rb +2 -2
- data/lib/shell/domain.rb +14 -0
- data/lib/shell/help_monkey_patch.rb +10 -0
- data/lib/shell/interactive_wizard.rb +4 -1
- data/lib/util/os_util.rb +14 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZDEyNmM1MGE3NzA2MzQ5OGMyMzhhNDVjZDUxY2JkMmE0MTYxNDFkYQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MWRiODEwOTRkYjNkZDRhNzI4ZjNmNjVjZmQ3ODQwMmI1Y2VjMTQwNQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MjE1MzUwZTNlZTMzMWY3OTRkMWJhNGJmNDQyZjU2YTM2YjkwYWFhZjczZjRh
|
10
|
+
ODY2NTVjOTI5M2Y2YzVkYjFhMzlhMmYzMTcwZDZiZmNjZDNmM2VhZWIzZGY3
|
11
|
+
MzMyYzBlZDM3ZDQxNjVlOGQ4MjYzNmY3ZWEwMmE1OTIxYjkzNDY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
26
|
-
|
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
|
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
|
20
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
-
|
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 "
|
128
|
-
def
|
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("
|
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("
|
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
|
-
|
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()
|
data/lib/commands/thor/node.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
14
|
-
|
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
|
-
|
47
|
+
username_exists = check_for_username_entry(client_username())
|
48
48
|
ssh_key_path = SshProcessing.default_rsa_pub_key_path()
|
49
49
|
|
50
|
-
{:
|
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
|
115
|
-
return if params[:
|
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
|
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
|
-
|
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
|
-
|
131
|
-
|
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
|
-
|
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
|
|
data/lib/domain/git_adapter.rb
CHANGED
@@ -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
|
22
|
-
|
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
|
data/lib/dtk-client/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module DtkClient
|
2
|
-
VERSION="0.5.
|
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,
|
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,
|
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
|
data/lib/parser/adapters/thor.rb
CHANGED
@@ -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 []
|
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.
|
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-
|
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.
|
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.
|