dtk-client 0.5.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/Gemfile +5 -0
- data/Gemfile_dev +12 -0
- data/README.md +78 -0
- data/bin/dtk +54 -0
- data/bin/dtk-shell +15 -0
- data/dtk-client.gemspec +49 -0
- data/lib/auxiliary.rb +13 -0
- data/lib/bundler_monkey_patch.rb +9 -0
- data/lib/client.rb +48 -0
- data/lib/command_helper.rb +16 -0
- data/lib/command_helpers/git_repo.rb +391 -0
- data/lib/command_helpers/jenkins_client/config_xml.rb +271 -0
- data/lib/command_helpers/jenkins_client.rb +91 -0
- data/lib/command_helpers/service_importer.rb +99 -0
- data/lib/command_helpers/service_link.rb +18 -0
- data/lib/command_helpers/ssh_processing.rb +43 -0
- data/lib/commands/common/thor/assembly_workspace.rb +1089 -0
- data/lib/commands/common/thor/clone.rb +39 -0
- data/lib/commands/common/thor/common.rb +34 -0
- data/lib/commands/common/thor/edit.rb +168 -0
- data/lib/commands/common/thor/list_diffs.rb +84 -0
- data/lib/commands/common/thor/pull_clone_changes.rb +11 -0
- data/lib/commands/common/thor/pull_from_remote.rb +99 -0
- data/lib/commands/common/thor/purge_clone.rb +26 -0
- data/lib/commands/common/thor/push_clone_changes.rb +45 -0
- data/lib/commands/common/thor/push_to_remote.rb +45 -0
- data/lib/commands/common/thor/reparse.rb +36 -0
- data/lib/commands/common/thor/set_required_params.rb +29 -0
- data/lib/commands/common/thor/task_status.rb +81 -0
- data/lib/commands/thor/account.rb +213 -0
- data/lib/commands/thor/assembly.rb +329 -0
- data/lib/commands/thor/attribute.rb +62 -0
- data/lib/commands/thor/component.rb +52 -0
- data/lib/commands/thor/component_module.rb +829 -0
- data/lib/commands/thor/component_template.rb +153 -0
- data/lib/commands/thor/dependency.rb +18 -0
- data/lib/commands/thor/developer.rb +105 -0
- data/lib/commands/thor/dtk.rb +117 -0
- data/lib/commands/thor/library.rb +107 -0
- data/lib/commands/thor/node.rb +411 -0
- data/lib/commands/thor/node_group.rb +211 -0
- data/lib/commands/thor/node_template.rb +88 -0
- data/lib/commands/thor/project.rb +17 -0
- data/lib/commands/thor/provider.rb +155 -0
- data/lib/commands/thor/repo.rb +35 -0
- data/lib/commands/thor/service.rb +656 -0
- data/lib/commands/thor/service_module.rb +806 -0
- data/lib/commands/thor/state_change.rb +10 -0
- data/lib/commands/thor/target.rb +94 -0
- data/lib/commands/thor/task.rb +100 -0
- data/lib/commands/thor/utils.rb +4 -0
- data/lib/commands/thor/workspace.rb +437 -0
- data/lib/commands.rb +40 -0
- data/lib/config/cacert.pem +3785 -0
- data/lib/config/client.conf.header +18 -0
- data/lib/config/configuration.rb +82 -0
- data/lib/config/default.conf +14 -0
- data/lib/config/disk_cacher.rb +60 -0
- data/lib/configurator.rb +92 -0
- data/lib/context_router.rb +23 -0
- data/lib/core.rb +460 -0
- data/lib/domain/git_adapter.rb +221 -0
- data/lib/domain/response.rb +234 -0
- data/lib/dtk-client/version.rb +3 -0
- data/lib/dtk_constants.rb +23 -0
- data/lib/dtk_logger.rb +96 -0
- data/lib/error.rb +74 -0
- data/lib/git-logs/git.log +0 -0
- data/lib/parser/adapters/option_parser.rb +53 -0
- data/lib/parser/adapters/thor/common_option_defs.rb +12 -0
- data/lib/parser/adapters/thor.rb +509 -0
- data/lib/require_first.rb +87 -0
- data/lib/search_hash.rb +27 -0
- data/lib/shell/context.rb +975 -0
- data/lib/shell/context_aux.rb +29 -0
- data/lib/shell/domain.rb +447 -0
- data/lib/shell/header_shell.rb +27 -0
- data/lib/shell/help_monkey_patch.rb +221 -0
- data/lib/shell/interactive_wizard.rb +233 -0
- data/lib/shell/parse_monkey_patch.rb +22 -0
- data/lib/shell/status_monitor.rb +105 -0
- data/lib/shell.rb +219 -0
- data/lib/util/console.rb +143 -0
- data/lib/util/dtk_puppet.rb +46 -0
- data/lib/util/os_util.rb +265 -0
- data/lib/view_processor/augmented_simple_list.rb +27 -0
- data/lib/view_processor/hash_pretty_print.rb +106 -0
- data/lib/view_processor/simple_list.rb +139 -0
- data/lib/view_processor/table_print.rb +277 -0
- data/lib/view_processor.rb +112 -0
- data/puppet/manifests/init.pp +72 -0
- data/puppet/manifests/params.pp +16 -0
- data/puppet/r8meta.puppet.yml +18 -0
- data/puppet/templates/bash_profile.erb +2 -0
- data/puppet/templates/client.conf.erb +1 -0
- data/puppet/templates/dtkclient.erb +2 -0
- data/spec/assembly_spec.rb +50 -0
- data/spec/assembly_template_spec.rb +51 -0
- data/spec/component_template_spec.rb +40 -0
- data/spec/dependency_spec.rb +6 -0
- data/spec/dtk_shell_spec.rb +13 -0
- data/spec/dtk_spec.rb +33 -0
- data/spec/lib/spec_helper.rb +10 -0
- data/spec/lib/spec_thor.rb +105 -0
- data/spec/module_spec.rb +35 -0
- data/spec/node_spec.rb +43 -0
- data/spec/node_template_spec.rb +25 -0
- data/spec/project_spec.rb +6 -0
- data/spec/repo_spec.rb +7 -0
- data/spec/response_spec.rb +52 -0
- data/spec/service_spec.rb +41 -0
- data/spec/state_change_spec.rb +7 -0
- data/spec/table_print_spec.rb +48 -0
- data/spec/target_spec.rb +57 -0
- data/spec/task_spec.rb +28 -0
- data/views/assembly/augmented_simple_list.rb +12 -0
- data/views/assembly_template/augmented_simple_list.rb +12 -0
- data/views/list_task/augmented_simple_list.rb +12 -0
- metadata +351 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
module DTK::Client
|
2
|
+
module TaskStatusMixin
|
3
|
+
def task_status_aux(id,type,wait_flag)
|
4
|
+
id_field = "#{type}_id".to_sym
|
5
|
+
if wait_flag
|
6
|
+
# there will be infinite loop until intereputed with CTRL+C
|
7
|
+
begin
|
8
|
+
response = nil
|
9
|
+
loop do
|
10
|
+
post_body = {
|
11
|
+
id_field => id,
|
12
|
+
:format => :table
|
13
|
+
}
|
14
|
+
response = post rest_url("#{type}/task_status"), post_body
|
15
|
+
|
16
|
+
raise DTK::Client::DtkError, "[ERROR] #{response['errors'].first['message']}." if response["status"].eql?('notok')
|
17
|
+
|
18
|
+
# stop pulling when top level task succeds, fails or timeout
|
19
|
+
if response and response.data and response.data.first
|
20
|
+
#TODO: may fix in server, but now top can have non executing state but a concurrent branch can execute; so
|
21
|
+
#chanding bloew for time being
|
22
|
+
#break unless response.data.first["status"].eql? "executing"
|
23
|
+
# TODO: There is bug where we do not see executing status on start so we have to wait until at
|
24
|
+
# least one 'successed' has been found
|
25
|
+
is_pending = (response.data.select {|r|r["status"].nil? }).size > 0
|
26
|
+
is_executing = (response.data.select {|r|r["status"].eql? "executing"}).size > 0
|
27
|
+
is_failed = (response.data.select {|r|r["status"].eql? "failed"}).size > 0
|
28
|
+
is_cancelled = response.data.first["status"].eql?("cancelled")
|
29
|
+
|
30
|
+
# when some of the converge tasks fail, stop task-status --wait and set task status to '' for remaining tasks which are not executed
|
31
|
+
if is_failed
|
32
|
+
response.data.each {|r| (r["status"] = "") if r["status"].eql?("executing")}
|
33
|
+
is_cancelled = true
|
34
|
+
end
|
35
|
+
|
36
|
+
unless (is_executing || is_pending) && !is_cancelled
|
37
|
+
system('clear')
|
38
|
+
response.print_error_table = true
|
39
|
+
response.render_table(:task_status)
|
40
|
+
return response
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
response.render_table(:task_status)
|
45
|
+
system('clear')
|
46
|
+
response.render_data(true)
|
47
|
+
|
48
|
+
Console.wait_animation("Watching '#{type}' task status [ #{DEBUG_SLEEP_TIME} seconds refresh ] ",DEBUG_SLEEP_TIME)
|
49
|
+
end
|
50
|
+
rescue Interrupt => e
|
51
|
+
puts ""
|
52
|
+
# this tells rest of the flow to skip rendering of this response
|
53
|
+
response.skip_render = true unless response.nil?
|
54
|
+
end
|
55
|
+
else
|
56
|
+
post_body = {
|
57
|
+
id_field => id,
|
58
|
+
:format => :table
|
59
|
+
}
|
60
|
+
response = post rest_url("#{type}/task_status"), post_body
|
61
|
+
response.print_error_table = true
|
62
|
+
response.render_table(:task_status)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def list_task_info_aux(type, id)
|
67
|
+
id_sym = "#{type}_id".to_sym
|
68
|
+
post_body = {
|
69
|
+
id_sym => id,
|
70
|
+
:format => :list
|
71
|
+
}
|
72
|
+
response = post rest_url("#{type}/task_status"), post_body
|
73
|
+
|
74
|
+
raise DTK::Client::DtkError, "[SERVER ERROR] #{response['errors'].first['message']}." if response["status"].eql?('notok')
|
75
|
+
|
76
|
+
response.override_command_class("list_task")
|
77
|
+
puts response.render_data
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
dtk_require_from_base('command_helpers/ssh_processing')
|
2
|
+
dtk_require_from_base("dtk_logger")
|
3
|
+
dtk_require_from_base("util/os_util")
|
4
|
+
dtk_require_from_base('configurator')
|
5
|
+
|
6
|
+
module DTK::Client
|
7
|
+
class Account < CommandBaseThor
|
8
|
+
include ParseFile
|
9
|
+
|
10
|
+
KEY_EXISTS_ALREADY_CONTENT = 'key exists already'
|
11
|
+
|
12
|
+
no_tasks do
|
13
|
+
def password_prompt(message, add_options=true)
|
14
|
+
begin
|
15
|
+
while line = Readline.readline("#{message}: ", add_hist = false)
|
16
|
+
raise Interrupt if line.empty?
|
17
|
+
return line
|
18
|
+
end
|
19
|
+
rescue Interrupt => e
|
20
|
+
retry
|
21
|
+
ensure
|
22
|
+
puts "\n" if line.nil?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.internal_add_user_access(url, post_body, component_name)
|
28
|
+
response = post(rest_url(url),post_body)
|
29
|
+
key_exists_already = (response.error_message||'').include?(KEY_EXISTS_ALREADY_CONTENT)
|
30
|
+
puts "Key exists already for #{component_name}" if key_exists_already
|
31
|
+
[response, key_exists_already]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.add_key(path_to_key, name=nil)
|
35
|
+
match, matched_username = nil, nil
|
36
|
+
|
37
|
+
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
|
40
|
+
end
|
41
|
+
|
42
|
+
rsa_pub_key = File.open(path_to_key){|f|f.read}
|
43
|
+
|
44
|
+
post_body = { :rsa_pub_key => rsa_pub_key.chomp }
|
45
|
+
|
46
|
+
post_body.merge!(:username => name.chomp) if name
|
47
|
+
proper_response = nil
|
48
|
+
response, key_exists_already = Account.internal_add_user_access("service_module/add_user_direct_access", post_body, 'service module')
|
49
|
+
return response unless (response.ok? || key_exists_already)
|
50
|
+
|
51
|
+
|
52
|
+
if response.ok?
|
53
|
+
proper_response = response
|
54
|
+
match = response.data['match']
|
55
|
+
matched_username = response.data['matched_username']
|
56
|
+
end
|
57
|
+
|
58
|
+
response, key_exists_already = Account.internal_add_user_access("component_module/add_user_direct_access", post_body, 'component module')
|
59
|
+
return response unless (response.ok? || key_exists_already)
|
60
|
+
proper_response = response if response.ok?
|
61
|
+
|
62
|
+
# if either of request passed we will add to known hosts
|
63
|
+
if match
|
64
|
+
OsUtil.print("Provided RSA public key already exists, user creation aborted!", :yellow)
|
65
|
+
elsif proper_response
|
66
|
+
repo_manager_fingerprint,repo_manager_dns = proper_response.data_ret_and_remove!(:repo_manager_fingerprint,:repo_manager_dns)
|
67
|
+
SshProcessing.update_ssh_known_hosts(repo_manager_dns,repo_manager_fingerprint)
|
68
|
+
OsUtil.print("Ssh key added successfully!", :yellow)
|
69
|
+
|
70
|
+
return proper_response
|
71
|
+
else
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
desc "set-password", "Change password for your dtk user account"
|
77
|
+
def set_password(context_params)
|
78
|
+
old_pass_prompt, old_pass, new_pass_prompt, confirm_pass_prompt = nil
|
79
|
+
cred_file = ::DTK::Client::Configurator.CRED_FILE
|
80
|
+
old_pass = parse_key_value_file(cred_file)[:password]
|
81
|
+
username = parse_key_value_file(cred_file)[:username]
|
82
|
+
|
83
|
+
if old_pass.nil?
|
84
|
+
OsUtil.print("Unable to retrieve your current password!", :yellow)
|
85
|
+
return
|
86
|
+
end
|
87
|
+
|
88
|
+
3.times do
|
89
|
+
old_pass_prompt = password_prompt("Enter old password")
|
90
|
+
|
91
|
+
break if (old_pass.eql?(old_pass_prompt) || old_pass_prompt.nil?)
|
92
|
+
OsUtil.print("Incorrect old password!", :yellow)
|
93
|
+
end
|
94
|
+
return unless old_pass.eql?(old_pass_prompt)
|
95
|
+
|
96
|
+
new_pass_prompt = password_prompt("Enter new password")
|
97
|
+
return if new_pass_prompt.nil?
|
98
|
+
confirm_pass_prompt = password_prompt("Confirm new password")
|
99
|
+
|
100
|
+
if new_pass_prompt.eql?(confirm_pass_prompt)
|
101
|
+
post_body = {:new_password => new_pass_prompt}
|
102
|
+
response = post rest_url("account/set_password"), post_body
|
103
|
+
return response unless response.ok?
|
104
|
+
|
105
|
+
::DTK::Client::Configurator.regenerate_conf_file(cred_file, [['username', "#{username.to_s}"], ['password', "#{new_pass_prompt.to_s}"]], '')
|
106
|
+
OsUtil.print("Password changed successfully!", :yellow)
|
107
|
+
else
|
108
|
+
OsUtil.print("Entered passwords don't match!", :yellow)
|
109
|
+
return
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
desc "list-ssh-keys", "Show list of keys that your account profile has saved"
|
114
|
+
def list_ssh_keys(context_params)
|
115
|
+
username = parse_key_value_file(::DTK::Client::Configurator.CRED_FILE)[:username]
|
116
|
+
post_body = {:username => username}
|
117
|
+
|
118
|
+
response = post rest_url("account/list_ssh_keys"), post_body
|
119
|
+
response.render_table(:account_ssh_keys)
|
120
|
+
end
|
121
|
+
|
122
|
+
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"
|
123
|
+
def add_ssh_key(context_params)
|
124
|
+
name, path_to_key = context_params.retrieve_arguments([:option_1!, :option_2],method_argument_names)
|
125
|
+
path_to_key ||= SshProcessing.default_rsa_pub_key_path()
|
126
|
+
access_granted = Account.add_key(path_to_key, name)
|
127
|
+
|
128
|
+
FileUtils.touch(DTK::Client::Configurator::DIRECT_ACCESS) if access_granted
|
129
|
+
end
|
130
|
+
|
131
|
+
desc "remove-ssh-key NAME ","Removes user and direct access to modules."
|
132
|
+
def remove_ssh_key(context_params)
|
133
|
+
name = context_params.retrieve_arguments([:option_1!],method_argument_names)
|
134
|
+
post_body = {:username => name.chomp}
|
135
|
+
|
136
|
+
response = post rest_url("component_module/remove_user_direct_access"), post_body
|
137
|
+
return response unless response.ok?
|
138
|
+
|
139
|
+
response = post rest_url("service_module/remove_user_direct_access"), post_body
|
140
|
+
return response unless response.ok?
|
141
|
+
|
142
|
+
OsUtil.print("Ssh key removed successfully!", :yellow)
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
# Will leave this commented for now until we check if above commands work as expected
|
148
|
+
#
|
149
|
+
# def self.add_access(path_to_key)
|
150
|
+
# unless File.file?(path_to_key)
|
151
|
+
# raise DTK::Client::DtkError,"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)"
|
152
|
+
# end
|
153
|
+
# rsa_pub_key = File.open(path_to_key){|f|f.read}
|
154
|
+
# post_body = {
|
155
|
+
# :rsa_pub_key => rsa_pub_key.chomp
|
156
|
+
# }
|
157
|
+
|
158
|
+
# proper_response = nil
|
159
|
+
|
160
|
+
# response, key_exists_already = Account.internal_add_user_access("service_module/add_user_direct_access", post_body, 'service module')
|
161
|
+
# return response unless (response.ok? || key_exists_already)
|
162
|
+
# proper_response = response if response.ok?
|
163
|
+
|
164
|
+
# response, key_exists_already = Account.internal_add_user_access("component_module/add_user_direct_access", post_body, 'component module')
|
165
|
+
# return response unless (response.ok? || key_exists_already)
|
166
|
+
# proper_response = response if response.ok?
|
167
|
+
|
168
|
+
# # if either of request passed we will add to known hosts
|
169
|
+
# if proper_response
|
170
|
+
# repo_manager_fingerprint,repo_manager_dns = proper_response.data_ret_and_remove!(:repo_manager_fingerprint,:repo_manager_dns)
|
171
|
+
# SshProcessing.update_ssh_known_hosts(repo_manager_dns,repo_manager_fingerprint)
|
172
|
+
# return proper_response
|
173
|
+
# else
|
174
|
+
# nil
|
175
|
+
# end
|
176
|
+
# end
|
177
|
+
|
178
|
+
# desc "add-direct-access [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"
|
179
|
+
# def add_direct_access(context_params)
|
180
|
+
# return
|
181
|
+
# path_to_key = context_params.retrieve_arguments([:option_1],method_argument_names)
|
182
|
+
# path_to_key ||= SshProcessing.default_rsa_pub_key_path()
|
183
|
+
# access_granted = Account.add_access(path_to_key)
|
184
|
+
|
185
|
+
# FileUtils.touch(DTK::Client::Configurator::DIRECT_ACCESS) if access_granted
|
186
|
+
# access_granted
|
187
|
+
# end
|
188
|
+
|
189
|
+
# desc "remove-direct-access [PATH-TO-RSA-PUB-KEY]","Removes direct access to modules. Optional paramaeters is path to a ssh rsa public key and default is <user-home-dir>/.ssh/id_rsa.pub"
|
190
|
+
# def remove_direct_access(context_params)
|
191
|
+
# path_to_key = context_params.retrieve_arguments([:option_1],method_argument_names)
|
192
|
+
# path_to_key ||= SshProcessing.default_rsa_pub_key_path()
|
193
|
+
|
194
|
+
# # path_to_key ||= "#{ENV['HOME']}/.ssh/id_rsa.pub" #TODO: very brittle
|
195
|
+
# unless File.file?(path_to_key)
|
196
|
+
# raise DTK::Client::DtkError,"No 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)"
|
197
|
+
# end
|
198
|
+
# rsa_pub_key = File.open(path_to_key){|f|f.read}
|
199
|
+
# post_body = {
|
200
|
+
# :rsa_pub_key => rsa_pub_key.chomp
|
201
|
+
# }
|
202
|
+
# response = post rest_url("component_module/remove_user_direct_access"), post_body
|
203
|
+
# return response unless response.ok?
|
204
|
+
|
205
|
+
# response = post rest_url("service_module/remove_user_direct_access"), post_body
|
206
|
+
# return response unless response.ok?
|
207
|
+
|
208
|
+
# FileUtils.rm(DTK::Client::Configurator::DIRECT_ACCESS) if File.exists?(DTK::Client::Configurator::DIRECT_ACCESS)
|
209
|
+
# return response
|
210
|
+
# end
|
211
|
+
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,329 @@
|
|
1
|
+
dtk_require("../../shell/status_monitor")
|
2
|
+
|
3
|
+
module DTK::Client
|
4
|
+
class Assembly < CommandBaseThor
|
5
|
+
no_tasks do
|
6
|
+
def get_assembly_name(assembly_id)
|
7
|
+
name = nil
|
8
|
+
3.times do
|
9
|
+
name = get_name_from_id_helper(assembly_id)
|
10
|
+
break if name
|
11
|
+
end
|
12
|
+
|
13
|
+
name
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_assembly_stage_name(assembly_list,assembly_template_name)
|
17
|
+
name = nil
|
18
|
+
current_list = assembly_list.select{|e| e.include?(assembly_template_name)}
|
19
|
+
|
20
|
+
if current_list.empty?
|
21
|
+
name = assembly_template_name
|
22
|
+
else
|
23
|
+
numbers = []
|
24
|
+
base_name = nil
|
25
|
+
|
26
|
+
assembly_list.each do |assembly|
|
27
|
+
match = assembly.match(/#{assembly_template_name}(-)(\d*)/)
|
28
|
+
base_name = assembly_template_name if assembly_template_name.include?(assembly)
|
29
|
+
numbers << match[2].to_i if match
|
30
|
+
end
|
31
|
+
|
32
|
+
unless base_name
|
33
|
+
name = assembly_template_name
|
34
|
+
else
|
35
|
+
highest = numbers.max||1
|
36
|
+
new_highest = highest+1
|
37
|
+
|
38
|
+
all = (2..new_highest).to_a
|
39
|
+
nums = all - numbers
|
40
|
+
name = assembly_template_name + "-#{nums.first}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
name
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.whoami()
|
49
|
+
return :assembly, "assembly/list", {:subtype => 'template'}
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.get_assembly_template_id_for_service(assembly_template_name, service)
|
53
|
+
assembly_template_id = nil
|
54
|
+
# TODO: See with Rich if there is better way to resolve this
|
55
|
+
response = DTK::Client::CommandBaseThor.get_cached_response(:assembly, "assembly/list", {:subtype => 'template' })
|
56
|
+
# response = DTK::Client::CommandBaseThor.get_cached_response(:module, "service_module/list")
|
57
|
+
|
58
|
+
if response.ok?
|
59
|
+
unless response['data'].nil?
|
60
|
+
response['data'].each do |module_item|
|
61
|
+
if ("#{service.to_s}::#{assembly_template_name.to_s}" == (module_item['display_name']))
|
62
|
+
assembly_template_id = module_item['id']
|
63
|
+
break
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
raise DTK::Client::DtkError, "Illegal name (#{assembly_template_name}) for assembly." if assembly_template_id.nil?
|
70
|
+
|
71
|
+
return assembly_template_id
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.get_assembly_template_name_for_service(assembly_template_id, service)
|
75
|
+
assembly_template_name = nil
|
76
|
+
# TODO: See with Rich if there is better way to resolve this
|
77
|
+
response = DTK::Client::CommandBaseThor.get_cached_response(:assembly, "assembly/list", {:subtype => 'template' })
|
78
|
+
|
79
|
+
if response.ok?
|
80
|
+
unless response['data'].nil?
|
81
|
+
response['data'].each do |module_item|
|
82
|
+
if assembly_template_id.to_i == module_item['id']
|
83
|
+
assembly_template_name = module_item['display_name'].gsub("#{service.to_s}::",'')
|
84
|
+
break
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
raise DTK::Client::DtkError, "Illegal name (#{assembly_template_name}) for assembly." if assembly_template_name.nil?
|
91
|
+
return assembly_template_name
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.pretty_print_cols()
|
95
|
+
PPColumns.get(:assembly)
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
# List assembly templates for specific module
|
100
|
+
def self.validation_list(context_params)
|
101
|
+
if context_params.is_there_identifier?(:"service-module")
|
102
|
+
service_module_id = context_params.retrieve_arguments([:service_module_id!])
|
103
|
+
get_cached_response(:assembly, "service_module/list_assemblies", { :service_module_id => service_module_id })
|
104
|
+
else
|
105
|
+
get_cached_response(:assembly, "assembly/list", {:subtype => 'template' })
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.assembly_list()
|
110
|
+
assembly_list = []
|
111
|
+
response = get_cached_response(:service, "assembly/list", {})
|
112
|
+
raise DTK::Client::DtkError, "Unable to retreive service list." unless (response.nil? || response.ok?)
|
113
|
+
|
114
|
+
if assemblies = response.data
|
115
|
+
assemblies.each do |assembly|
|
116
|
+
assembly_list << assembly["display_name"]
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
assembly_list
|
121
|
+
end
|
122
|
+
|
123
|
+
desc "ASSEMBLY-NAME/ID info", "Get information about given assembly."
|
124
|
+
method_option :list, :type => :boolean, :default => false
|
125
|
+
def info(context_params)
|
126
|
+
assembly_template_id = context_params.retrieve_arguments([:assembly_id!],method_argument_names)
|
127
|
+
data_type = :assembly_template
|
128
|
+
|
129
|
+
post_body = {
|
130
|
+
:assembly_id => assembly_template_id,
|
131
|
+
:subtype => 'template',
|
132
|
+
}
|
133
|
+
|
134
|
+
post rest_url("assembly/info"), post_body
|
135
|
+
end
|
136
|
+
|
137
|
+
desc "ASSEMBLY-NAME/ID list-nodes [--service SERVICE-NAME]", "List all nodes for given assembly."
|
138
|
+
method_option :list, :type => :boolean, :default => false
|
139
|
+
method_option "service",:aliases => "-s" ,
|
140
|
+
:type => :string,
|
141
|
+
:banner => "SERVICE-LIST-FILTER",
|
142
|
+
:desc => "Service list filter"
|
143
|
+
def list_nodes(context_params)
|
144
|
+
context_params.method_arguments = ["nodes"]
|
145
|
+
list(context_params)
|
146
|
+
end
|
147
|
+
|
148
|
+
desc "ASSEMBLY-NAME/ID list-components [--service SERVICE-NAME]", "List all components for given assembly."
|
149
|
+
method_option :list, :type => :boolean, :default => false
|
150
|
+
method_option "service",:aliases => "-s" ,
|
151
|
+
:type => :string,
|
152
|
+
:banner => "SERVICE-LIST-FILTER",
|
153
|
+
:desc => "Service list filter"
|
154
|
+
def list_components(context_params)
|
155
|
+
context_params.method_arguments = ["components"]
|
156
|
+
list(context_params)
|
157
|
+
end
|
158
|
+
|
159
|
+
# desc "[ASSEMBLY-TEMPLATE-NAME/ID] show [nodes|components|targets]", "List all nodes/components/targets for given assembly template."
|
160
|
+
#TODO: temporaily taking out target option
|
161
|
+
desc "list", "List all assemblies."
|
162
|
+
def list(context_params)
|
163
|
+
assembly_template_id, about, service_filter = context_params.retrieve_arguments([:assembly_id, :option_1, :option_1],method_argument_names)
|
164
|
+
|
165
|
+
if assembly_template_id.nil?
|
166
|
+
|
167
|
+
if options.service
|
168
|
+
service_id = options.service
|
169
|
+
context_params_for_service = DTK::Shell::ContextParams.new
|
170
|
+
context_params_for_service.add_context_to_params("service_module", "service_module", service_id)
|
171
|
+
context_params_for_service.method_arguments = ['assembly',"#{service_id}"]
|
172
|
+
|
173
|
+
response = DTK::Client::ContextRouter.routeTask("service_module", "list", context_params_for_service, @conn)
|
174
|
+
else
|
175
|
+
response = post rest_url("assembly/list"), {:subtype => 'template', :detail_level => 'nodes'}
|
176
|
+
data_type = :assembly_template
|
177
|
+
response.render_table(data_type) unless options.list?
|
178
|
+
return response
|
179
|
+
end
|
180
|
+
|
181
|
+
else
|
182
|
+
|
183
|
+
post_body = {
|
184
|
+
:subtype => 'template',
|
185
|
+
:assembly_id => assembly_template_id,
|
186
|
+
:about => about
|
187
|
+
}
|
188
|
+
|
189
|
+
case about
|
190
|
+
when 'nodes'
|
191
|
+
response = post rest_url("assembly/info_about"), post_body
|
192
|
+
data_type = :node_template
|
193
|
+
when 'components'
|
194
|
+
response = post rest_url("assembly/info_about"), post_body
|
195
|
+
data_type = :component
|
196
|
+
# when 'attributes'
|
197
|
+
# response = post rest_url("assembly/info_about"), post_body
|
198
|
+
# data_type = :attribute
|
199
|
+
else
|
200
|
+
raise_validation_error_method_usage('list')
|
201
|
+
end
|
202
|
+
|
203
|
+
response.render_table(data_type) unless options.list?
|
204
|
+
|
205
|
+
return response
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
desc "ASSEMBLY-NAME/ID stage [INSTANCE-NAME] [-t TARGET-NAME/ID]", "Stage assembly in target."
|
210
|
+
method_option "in-target",:aliases => "-t" ,
|
211
|
+
:type => :string,
|
212
|
+
:banner => "TARGET-NAME/ID",
|
213
|
+
:desc => "Target (id) to create assembly in"
|
214
|
+
def stage(context_params)
|
215
|
+
assembly_template_id, name = context_params.retrieve_arguments([:assembly_id!, :option_1],method_argument_names)
|
216
|
+
post_body = {
|
217
|
+
:assembly_id => assembly_template_id
|
218
|
+
}
|
219
|
+
|
220
|
+
assembly_template_name = get_assembly_name(assembly_template_id)
|
221
|
+
assembly_template_name.gsub!('::','-') if assembly_template_name
|
222
|
+
|
223
|
+
# we check current options and forwarded options (from deploy method)
|
224
|
+
in_target = options["in-target"] || context_params.get_forwarded_thor_option("in-target")
|
225
|
+
assembly_list = Assembly.assembly_list()
|
226
|
+
|
227
|
+
if name
|
228
|
+
raise DTK::Client::DtkValidationError, "Unable to stage service with name '#{name}'. Service with specified name exists already!" if assembly_list.include?(name)
|
229
|
+
else
|
230
|
+
name = get_assembly_stage_name(assembly_list,assembly_template_name)
|
231
|
+
end
|
232
|
+
|
233
|
+
post_body.merge!(:target_id => in_target) if in_target
|
234
|
+
post_body.merge!(:name => name) if name
|
235
|
+
|
236
|
+
response = post rest_url("assembly/stage"), post_body
|
237
|
+
return response unless response.ok?
|
238
|
+
# when changing context send request for getting latest assemblies instead of getting from cache
|
239
|
+
@@invalidate_map << :service
|
240
|
+
@@invalidate_map << :assembly
|
241
|
+
|
242
|
+
return response
|
243
|
+
end
|
244
|
+
|
245
|
+
# desc "ASSEMBLY-NAME/ID deploy [-v VERSION] [INSTANCE-NAME] [-t TARGET-NAME/ID] [-m COMMIT-MSG]", "Stage and deploy assembly in target."
|
246
|
+
# version_method_option
|
247
|
+
desc "ASSEMBLY-NAME/ID deploy [INSTANCE-NAME] [-t TARGET-NAME/ID] [-m COMMIT-MSG]", "Stage and deploy assembly in target."
|
248
|
+
method_option "in-target",:aliases => "-t" ,
|
249
|
+
:type => :string,
|
250
|
+
:banner => "TARGET-NAME/ID",
|
251
|
+
:desc => "Target (id) to create assembly in"
|
252
|
+
method_option "commit_msg",:aliases => "-m" ,
|
253
|
+
:type => :string,
|
254
|
+
:banner => "COMMIT-MSG",
|
255
|
+
:desc => "Commit message"
|
256
|
+
def deploy(context_params)
|
257
|
+
context_params.forward_options(options)
|
258
|
+
response = stage(context_params)
|
259
|
+
|
260
|
+
return response unless response.ok?
|
261
|
+
|
262
|
+
# create task
|
263
|
+
# commented assemlby_id until we implement json to yaml parsing on client side instead of server side
|
264
|
+
# assembly_id = response.data(:assembly_id)
|
265
|
+
|
266
|
+
# temp solution just to make deploy to work, since response we get from 'stage' command is simple string presented as yaml
|
267
|
+
assembly_id = response.data.match(/(id:)\s*(\d+)/)[2]
|
268
|
+
|
269
|
+
post_body = {
|
270
|
+
:assembly_id => assembly_id,
|
271
|
+
:commit_msg => options["commit_msg"]||"Initial deploy"
|
272
|
+
}
|
273
|
+
|
274
|
+
response = post rest_url("assembly/find_violations"), post_body
|
275
|
+
return response unless response.ok?
|
276
|
+
if response.data and response.data.size > 0
|
277
|
+
error_message = "The following violations were found; they must be corrected before the assembly can be deployed"
|
278
|
+
DTK::Client::OsUtil.print(error_message, :red)
|
279
|
+
return response.render_table(:violation)
|
280
|
+
end
|
281
|
+
|
282
|
+
ret = response = post(rest_url("assembly/create_task"), post_body)
|
283
|
+
|
284
|
+
return response unless response.ok?
|
285
|
+
|
286
|
+
# execute task
|
287
|
+
task_id = response.data(:task_id)
|
288
|
+
response = post(rest_url("task/execute"), "task_id" => task_id)
|
289
|
+
|
290
|
+
# start watching task ID
|
291
|
+
if $shell_mode
|
292
|
+
DTK::Shell::StatusMonitor.start_monitoring(task_id) if response.ok?
|
293
|
+
end
|
294
|
+
|
295
|
+
return response unless response.ok?
|
296
|
+
ret.add_data_value!(:task_id,task_id)
|
297
|
+
|
298
|
+
# when changing context send request for getting latest assemblies instead of getting from cache
|
299
|
+
@@invalidate_map << :service
|
300
|
+
|
301
|
+
return ret
|
302
|
+
end
|
303
|
+
|
304
|
+
|
305
|
+
desc "delete ASSEMBLY-ID", "Delete assembly"
|
306
|
+
method_option :force, :aliases => '-y', :type => :boolean, :default => false
|
307
|
+
def delete(context_params)
|
308
|
+
assembly_template_id = context_params.retrieve_arguments([:option_1!],method_argument_names)
|
309
|
+
unless options.force?
|
310
|
+
# Ask user if really want to delete assembly-template, if not then return to dtk-shell without deleting
|
311
|
+
return unless Console.confirmation_prompt("Are you sure you want to delete assembly '#{assembly_template_id}'"+"?")
|
312
|
+
end
|
313
|
+
|
314
|
+
post_body = {
|
315
|
+
:assembly_id => assembly_template_id,
|
316
|
+
:subtype => :template
|
317
|
+
}
|
318
|
+
response = post rest_url("assembly/delete"), post_body
|
319
|
+
|
320
|
+
# when changing context send request for getting latest assemblies instead of getting from cache
|
321
|
+
@@invalidate_map << :assembly
|
322
|
+
return response unless response.ok?
|
323
|
+
module_name,branch = response.data(:module_name,:workspace_branch)
|
324
|
+
response = Helper(:git_repo).pull_changes?(:service_module,module_name,:local_branch => branch)
|
325
|
+
return response unless response.ok?()
|
326
|
+
Response::Ok.new()
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
|
2
|
+
module DTK::Client
|
3
|
+
class Attribute < CommandBaseThor
|
4
|
+
|
5
|
+
no_tasks do
|
6
|
+
|
7
|
+
def self.assembly_validation_list(context_params)
|
8
|
+
assembly_or_worspace_id, node_id, component_id = context_params.retrieve_arguments([[:service_id!, :workspace_id!], :node_id!, :component_id!])
|
9
|
+
|
10
|
+
post_body = {
|
11
|
+
:assembly_id => assembly_or_worspace_id,
|
12
|
+
:node_id => node_id,
|
13
|
+
:component_id => component_id,
|
14
|
+
:subtype => 'instance',
|
15
|
+
:about => 'attributes',
|
16
|
+
:filter => nil
|
17
|
+
}
|
18
|
+
|
19
|
+
response = get_cached_response(:service_node_component_attribute, "assembly/info_about", post_body)
|
20
|
+
modified_response = response.clone_me()
|
21
|
+
|
22
|
+
modified_response['data'].each { |e| e['display_name'] = e['display_name'].split('/').last }
|
23
|
+
|
24
|
+
return modified_response
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.module_validation_list(context_params)
|
28
|
+
component_module_id = context_params.retrieve_arguments([:module_id!])
|
29
|
+
|
30
|
+
post_body = {
|
31
|
+
:component_module_id => component_module_id,
|
32
|
+
:about => :attributes
|
33
|
+
}
|
34
|
+
response = post rest_url("component_module/info_about"), post_body
|
35
|
+
|
36
|
+
modified_response = response.clone_me()
|
37
|
+
modified_response['data'].each { |e| e['display_name'] = e['display_name'].split('/').last }
|
38
|
+
#modified_response['data'].each { |e| e['display_name'] = e['display_name'].match(/.+\[.+::(.*)\]/)[1] }
|
39
|
+
|
40
|
+
return modified_response
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.validation_list(context_params)
|
46
|
+
command_name = context_params.root_command_name
|
47
|
+
|
48
|
+
case command_name
|
49
|
+
when 'service'
|
50
|
+
return assembly_validation_list(context_params)
|
51
|
+
when 'workspace'
|
52
|
+
return assembly_validation_list(context_params)
|
53
|
+
when 'module'
|
54
|
+
return module_validation_list(context_params)
|
55
|
+
else
|
56
|
+
raise DTK::Client::DtkError,"Attribute 'validation_list' not supported for #{command_name}, implementation nedeed."
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|