dtk-shell 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +5 -0
  3. data/Gemfile_dev +13 -0
  4. data/README.md +121 -0
  5. data/bin/dtk-execute +32 -0
  6. data/bin/dtk-run +92 -0
  7. data/bin/dtk-shell +31 -0
  8. data/dtk-shell.gemspec +50 -0
  9. data/lib/auxiliary.rb +61 -0
  10. data/lib/bundler_monkey_patch.rb +26 -0
  11. data/lib/client.rb +58 -0
  12. data/lib/command_helper.rb +33 -0
  13. data/lib/command_helpers/git_repo.rb +589 -0
  14. data/lib/command_helpers/git_repo/merge.rb +153 -0
  15. data/lib/command_helpers/jenkins_client.rb +106 -0
  16. data/lib/command_helpers/jenkins_client/config_xml.rb +288 -0
  17. data/lib/command_helpers/service_importer.rb +251 -0
  18. data/lib/command_helpers/service_link.rb +33 -0
  19. data/lib/command_helpers/test_module_creator.rb +69 -0
  20. data/lib/command_helpers/test_module_templates/dtk.model.yaml.eruby +10 -0
  21. data/lib/command_helpers/test_module_templates/spec_helper.rb.eruby +10 -0
  22. data/lib/command_helpers/test_module_templates/temp_component_spec.rb.eruby +5 -0
  23. data/lib/commands.rb +57 -0
  24. data/lib/commands/common/thor/access_control.rb +133 -0
  25. data/lib/commands/common/thor/action_result_handler.rb +74 -0
  26. data/lib/commands/common/thor/assembly_template.rb +92 -0
  27. data/lib/commands/common/thor/assembly_workspace.rb +1801 -0
  28. data/lib/commands/common/thor/base_command_helper.rb +59 -0
  29. data/lib/commands/common/thor/clone.rb +82 -0
  30. data/lib/commands/common/thor/common.rb +88 -0
  31. data/lib/commands/common/thor/common_base.rb +49 -0
  32. data/lib/commands/common/thor/create_target.rb +70 -0
  33. data/lib/commands/common/thor/edit.rb +255 -0
  34. data/lib/commands/common/thor/inventory_parser.rb +98 -0
  35. data/lib/commands/common/thor/list_diffs.rb +128 -0
  36. data/lib/commands/common/thor/module.rb +1011 -0
  37. data/lib/commands/common/thor/module/import.rb +210 -0
  38. data/lib/commands/common/thor/node.rb +53 -0
  39. data/lib/commands/common/thor/poller.rb +65 -0
  40. data/lib/commands/common/thor/pull_clone_changes.rb +28 -0
  41. data/lib/commands/common/thor/pull_from_remote.rb +152 -0
  42. data/lib/commands/common/thor/puppet_forge.rb +72 -0
  43. data/lib/commands/common/thor/purge_clone.rb +101 -0
  44. data/lib/commands/common/thor/push_clone_changes.rb +162 -0
  45. data/lib/commands/common/thor/push_to_remote.rb +94 -0
  46. data/lib/commands/common/thor/remotes.rb +71 -0
  47. data/lib/commands/common/thor/reparse.rb +40 -0
  48. data/lib/commands/common/thor/set_required_attributes.rb +46 -0
  49. data/lib/commands/thor/account.rb +239 -0
  50. data/lib/commands/thor/assembly.rb +356 -0
  51. data/lib/commands/thor/attribute.rb +79 -0
  52. data/lib/commands/thor/component.rb +70 -0
  53. data/lib/commands/thor/component_module.rb +501 -0
  54. data/lib/commands/thor/component_template.rb +174 -0
  55. data/lib/commands/thor/dependency.rb +34 -0
  56. data/lib/commands/thor/developer.rb +144 -0
  57. data/lib/commands/thor/dtk.rb +152 -0
  58. data/lib/commands/thor/library.rb +125 -0
  59. data/lib/commands/thor/node.rb +504 -0
  60. data/lib/commands/thor/node_template.rb +94 -0
  61. data/lib/commands/thor/project.rb +34 -0
  62. data/lib/commands/thor/provider.rb +233 -0
  63. data/lib/commands/thor/remotes.rb +49 -0
  64. data/lib/commands/thor/service.rb +941 -0
  65. data/lib/commands/thor/service_module.rb +914 -0
  66. data/lib/commands/thor/state_change.rb +25 -0
  67. data/lib/commands/thor/target.rb +250 -0
  68. data/lib/commands/thor/task.rb +116 -0
  69. data/lib/commands/thor/test_module.rb +310 -0
  70. data/lib/commands/thor/utils.rb +21 -0
  71. data/lib/commands/thor/workspace.rb +685 -0
  72. data/lib/config/cacert.pem +3785 -0
  73. data/lib/config/client.conf.header +20 -0
  74. data/lib/config/configuration.rb +99 -0
  75. data/lib/config/default.conf +16 -0
  76. data/lib/config/disk_cacher.rb +80 -0
  77. data/lib/configurator.rb +176 -0
  78. data/lib/context_router.rb +44 -0
  79. data/lib/core.rb +497 -0
  80. data/lib/domain/git_adapter.rb +412 -0
  81. data/lib/domain/git_error_handler.rb +64 -0
  82. data/lib/domain/response.rb +285 -0
  83. data/lib/domain/response/error_handler.rb +86 -0
  84. data/lib/dtk-shell/version.rb +20 -0
  85. data/lib/dtk_constants.rb +40 -0
  86. data/lib/dtk_error.rb +114 -0
  87. data/lib/dtk_logger.rb +126 -0
  88. data/lib/dtk_shell.rb +31 -0
  89. data/lib/error.rb +85 -0
  90. data/lib/execute.rb +29 -0
  91. data/lib/execute/cli_pure/cli_rerouter.rb +102 -0
  92. data/lib/execute/command.rb +40 -0
  93. data/lib/execute/command/api_call.rb +60 -0
  94. data/lib/execute/command/api_call/map.rb +60 -0
  95. data/lib/execute/command/api_call/service.rb +91 -0
  96. data/lib/execute/command/api_call/translation_term.rb +119 -0
  97. data/lib/execute/command/rest_call.rb +37 -0
  98. data/lib/execute/command_processor.rb +30 -0
  99. data/lib/execute/command_processor/rest_call.rb +59 -0
  100. data/lib/execute/error_usage.rb +21 -0
  101. data/lib/execute/execute_context.rb +86 -0
  102. data/lib/execute/execute_context/result_store.rb +37 -0
  103. data/lib/execute/script.rb +64 -0
  104. data/lib/execute/script/add_tenant.rb +121 -0
  105. data/lib/git-logs/git.log +0 -0
  106. data/lib/parser/adapters/option_parser.rb +70 -0
  107. data/lib/parser/adapters/thor.rb +555 -0
  108. data/lib/parser/adapters/thor/common_option_defs.rb +40 -0
  109. data/lib/require_first.rb +104 -0
  110. data/lib/search_hash.rb +44 -0
  111. data/lib/shell.rb +261 -0
  112. data/lib/shell/context.rb +1065 -0
  113. data/lib/shell/context_aux.rb +46 -0
  114. data/lib/shell/domain/active_context.rb +186 -0
  115. data/lib/shell/domain/context_entity.rb +89 -0
  116. data/lib/shell/domain/context_params.rb +223 -0
  117. data/lib/shell/domain/override_tasks.rb +88 -0
  118. data/lib/shell/domain/shadow_entity.rb +76 -0
  119. data/lib/shell/header_shell.rb +44 -0
  120. data/lib/shell/help_monkey_patch.rb +283 -0
  121. data/lib/shell/interactive_wizard.rb +225 -0
  122. data/lib/shell/message_queue.rb +63 -0
  123. data/lib/shell/parse_monkey_patch.rb +39 -0
  124. data/lib/shell/status_monitor.rb +124 -0
  125. data/lib/task_status.rb +83 -0
  126. data/lib/task_status/refresh_mode.rb +77 -0
  127. data/lib/task_status/snapshot_mode.rb +28 -0
  128. data/lib/task_status/stream_mode.rb +48 -0
  129. data/lib/task_status/stream_mode/element.rb +101 -0
  130. data/lib/task_status/stream_mode/element/format.rb +101 -0
  131. data/lib/task_status/stream_mode/element/hierarchical_task.rb +100 -0
  132. data/lib/task_status/stream_mode/element/hierarchical_task/result.rb +72 -0
  133. data/lib/task_status/stream_mode/element/hierarchical_task/result/action.rb +93 -0
  134. data/lib/task_status/stream_mode/element/hierarchical_task/result/components.rb +26 -0
  135. data/lib/task_status/stream_mode/element/hierarchical_task/result/node_level.rb +26 -0
  136. data/lib/task_status/stream_mode/element/hierarchical_task/steps.rb +34 -0
  137. data/lib/task_status/stream_mode/element/hierarchical_task/steps/action.rb +53 -0
  138. data/lib/task_status/stream_mode/element/hierarchical_task/steps/components.rb +53 -0
  139. data/lib/task_status/stream_mode/element/hierarchical_task/steps/node_level.rb +42 -0
  140. data/lib/task_status/stream_mode/element/no_results.rb +26 -0
  141. data/lib/task_status/stream_mode/element/render.rb +59 -0
  142. data/lib/task_status/stream_mode/element/stage.rb +84 -0
  143. data/lib/task_status/stream_mode/element/stage/render.rb +76 -0
  144. data/lib/task_status/stream_mode/element/task_end.rb +35 -0
  145. data/lib/task_status/stream_mode/element/task_start.rb +37 -0
  146. data/lib/util/common_util.rb +37 -0
  147. data/lib/util/console.rb +235 -0
  148. data/lib/util/dtk_puppet.rb +65 -0
  149. data/lib/util/module_util.rb +66 -0
  150. data/lib/util/os_util.rb +385 -0
  151. data/lib/util/permission_util.rb +31 -0
  152. data/lib/util/remote_dependency_util.rb +84 -0
  153. data/lib/util/ssh_util.rb +94 -0
  154. data/lib/view_processor.rb +129 -0
  155. data/lib/view_processor/augmented_simple_list.rb +44 -0
  156. data/lib/view_processor/hash_pretty_print.rb +123 -0
  157. data/lib/view_processor/simple_list.rb +156 -0
  158. data/lib/view_processor/table_print.rb +309 -0
  159. data/lib/violation.rb +86 -0
  160. data/lib/violation/attribute.rb +76 -0
  161. data/lib/violation/fix.rb +26 -0
  162. data/lib/violation/fix/result.rb +73 -0
  163. data/lib/violation/fix/result/error.rb +34 -0
  164. data/lib/violation/fix/set_attribute.rb +41 -0
  165. data/lib/violation/sub_classes.rb +60 -0
  166. data/puppet/manifests/init.pp +72 -0
  167. data/puppet/manifests/params.pp +16 -0
  168. data/puppet/r8meta.puppet.yml +35 -0
  169. data/puppet/templates/bash_profile.erb +2 -0
  170. data/puppet/templates/client.conf.erb +1 -0
  171. data/puppet/templates/dtkclient.erb +2 -0
  172. data/spec/component_module_spec.rb +34 -0
  173. data/spec/dependency_spec.rb +6 -0
  174. data/spec/dtk_shell_spec.rb +13 -0
  175. data/spec/dtk_spec.rb +33 -0
  176. data/spec/lib/spec_helper.rb +10 -0
  177. data/spec/lib/spec_thor.rb +108 -0
  178. data/spec/node_template_spec.rb +24 -0
  179. data/spec/project_spec.rb +6 -0
  180. data/spec/repo_spec.rb +7 -0
  181. data/spec/response_spec.rb +52 -0
  182. data/spec/service_module_spec.rb +38 -0
  183. data/spec/service_spec.rb +50 -0
  184. data/spec/state_change_spec.rb +7 -0
  185. data/spec/table_print_spec.rb +48 -0
  186. data/spec/target_spec.rb +57 -0
  187. data/spec/task_spec.rb +28 -0
  188. data/views/assembly/augmented_simple_list.rb +12 -0
  189. data/views/assembly_template/augmented_simple_list.rb +12 -0
  190. data/views/list_task/augmented_simple_list.rb +12 -0
  191. metadata +421 -0
@@ -0,0 +1,40 @@
1
+ #
2
+ # Copyright (C) 2010-2016 dtk contributors
3
+ #
4
+ # This file is part of the dtk project.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ require 'yaml'
19
+
20
+ module DTK::Client
21
+ module ReparseMixin
22
+ YamlDTKMetaFiles = ['dtk.model.yaml', 'module_refs.yaml', 'assemblies/*.yaml', 'assemblies/*/assembly.yaml']
23
+
24
+ def reparse_aux(location)
25
+ files_yaml = YamlDTKMetaFiles.map{|rel_path|Dir.glob("#{location}/#{rel_path}")}.flatten(1)
26
+ files_yaml.each do |file|
27
+ file_content = File.open(file).read
28
+ begin
29
+ YAML.load(file_content)
30
+ rescue Exception => e
31
+ e.to_s.gsub!(/\(<unknown>\)/,'')
32
+ raise DTK::Client::DSLParsing::YAMLParsing.new("YAML parsing error #{e} in file", file)
33
+ end
34
+ end
35
+
36
+ Response::Ok.new()
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,46 @@
1
+ #
2
+ # Copyright (C) 2010-2016 dtk contributors
3
+ #
4
+ # This file is part of the dtk project.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ module DTK; module Client
19
+ module SetRequiredParamsMixin
20
+ def set_required_attributes_aux(id, type, subtype = nil, additional_message = nil)
21
+ id_field = "#{type}_id".to_sym
22
+ post_body = {
23
+ id_field => id,
24
+ :subtype => 'instance',
25
+ :filter => 'required_unset_attributes'
26
+ }
27
+ post_body.merge!(:subtype => subtype.to_s) if subtype
28
+ response = post rest_url("#{type}/get_attributes"), post_body
29
+ return response unless response.ok?
30
+ missing_params = response.data
31
+ if missing_params.empty?
32
+ response.set_data('Message' => "No parameters to set.")
33
+ response
34
+ else
35
+ param_bindings = Shell::InteractiveWizard.resolve_missing_params(missing_params, additional_message)
36
+ post_body = {
37
+ id_field => id,
38
+ :av_pairs_hash => param_bindings.inject(Hash.new){|h,r|h.merge(r[:id] => r[:value])}
39
+ }
40
+ response = post rest_url("#{type}/set_attributes"), post_body
41
+ return response unless response.ok?
42
+ response.data
43
+ end
44
+ end
45
+ end
46
+ end; end
@@ -0,0 +1,239 @@
1
+ #
2
+ # Copyright (C) 2010-2016 dtk contributors
3
+ #
4
+ # This file is part of the dtk project.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ dtk_require_from_base("dtk_logger")
19
+ dtk_require_from_base("util/os_util")
20
+ dtk_require_from_base('configurator')
21
+
22
+ module DTK::Client
23
+ class Account < CommandBaseThor
24
+ include ParseFile
25
+
26
+ KEY_EXISTS_ALREADY_CONTENT = 'key exists already'
27
+
28
+ no_tasks do
29
+
30
+ def password_prompt(message, add_options=true)
31
+ begin
32
+ # while line = Readline.readline("#{message}: ", add_hist = false)
33
+ # using 'ask' from highline gem to be able to hide input for key and secret
34
+ while line = (HighLine.ask("#{message}") { |q| q.echo = false})
35
+ raise Interrupt if line.empty?
36
+ return line
37
+ end
38
+ rescue Interrupt
39
+ return nil
40
+ ensure
41
+ puts "\n" if line.nil?
42
+ end
43
+ end
44
+ end
45
+
46
+ def self.extended_context()
47
+ {
48
+ :context => {
49
+ :delete_ssh_key => {
50
+ :field => "display_name",
51
+ :url => "account/list_ssh_keys",
52
+ :opts => { :username => "#{Configurator.client_username}" }
53
+ }
54
+ },
55
+ :command => {
56
+ }
57
+ }
58
+ end
59
+
60
+ def self.internal_add_user_access(url, post_body, component_name)
61
+ response = post(rest_url(url),post_body)
62
+ key_exists_already = (response.error_message||'').include?(KEY_EXISTS_ALREADY_CONTENT)
63
+ puts "Key exists already for #{component_name}" if key_exists_already
64
+ [response, key_exists_already]
65
+ end
66
+
67
+ def self.add_key(path_to_key, first_registration=false, name='dtk-client')
68
+ match, matched_username = nil, nil
69
+
70
+ unless File.file?(path_to_key)
71
+ # 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
72
+ 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`)."
73
+ end
74
+
75
+ rsa_pub_key = SSHUtil.read_and_validate_pub_key(path_to_key)
76
+
77
+ post_body = { :rsa_pub_key => rsa_pub_key.chomp }
78
+ post_body.merge!(:username => name.chomp) if name
79
+ post_body.merge!(:first_registration => first_registration)
80
+
81
+ proper_response = nil
82
+ response, key_exists_already = Account.internal_add_user_access("account/add_user_direct_access", post_body, 'service module')
83
+
84
+ return response unless (response.ok? || key_exists_already)
85
+
86
+ match = response.data['match']
87
+ matched_username = response.data['matched_username']
88
+
89
+ if response && !match
90
+ repo_manager_fingerprint,repo_manager_dns = response.data_ret_and_remove!(:repo_manager_fingerprint,:repo_manager_dns)
91
+
92
+ SSHUtil.update_ssh_known_hosts(repo_manager_dns,repo_manager_fingerprint)
93
+ name = response.data["new_username"]
94
+
95
+ OsUtil.print("SSH key '#{name}' added successfully!", :yellow)
96
+
97
+ end
98
+
99
+ return response, match, matched_username
100
+ end
101
+
102
+ desc "set-password", "Change password for your dtk user account"
103
+ def set_password(context_params)
104
+ old_pass_prompt, old_pass, new_pass_prompt, confirm_pass_prompt = nil
105
+ cred_file = Configurator::CRED_FILE
106
+ old_pass = parse_key_value_file(cred_file)[:password]
107
+ username = parse_key_value_file(cred_file)[:username]
108
+
109
+ if old_pass.nil?
110
+ OsUtil.print("Unable to retrieve your current password!", :yellow)
111
+ return
112
+ end
113
+
114
+ 3.times do
115
+ old_pass_prompt = password_prompt("Enter old password: ")
116
+
117
+ break if (old_pass.eql?(old_pass_prompt) || old_pass_prompt.nil?)
118
+ OsUtil.print("Incorrect old password!", :yellow)
119
+ end
120
+ return unless old_pass.eql?(old_pass_prompt)
121
+
122
+ new_pass_prompt = password_prompt("Enter new password: ")
123
+ return if new_pass_prompt.nil?
124
+ confirm_pass_prompt = password_prompt("Confirm new password: ")
125
+
126
+ if new_pass_prompt.eql?(confirm_pass_prompt)
127
+ post_body = {:new_password => new_pass_prompt}
128
+ response = post rest_url("account/set_password"), post_body
129
+ return response unless response.ok?
130
+
131
+ Configurator.regenerate_conf_file(cred_file, [['username', "#{username.to_s}"], ['password', "#{new_pass_prompt.to_s}"]], '')
132
+ OsUtil.print("Password changed successfully!", :yellow)
133
+ else
134
+ OsUtil.print("Entered passwords don't match!", :yellow)
135
+ return
136
+ end
137
+ end
138
+
139
+ desc "list-ssh-keys", "Show list of key pairs that your account profile has saved"
140
+ def list_ssh_keys(context_params)
141
+ post_body = {:username => Configurator.client_username }
142
+ response = post rest_url("account/list_ssh_keys"), post_body
143
+ response.render_table(:account_ssh_keys)
144
+ end
145
+
146
+ 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"
147
+ def add_ssh_key(context_params)
148
+ name, path_to_key = context_params.retrieve_arguments([:option_1!, :option_2],method_argument_names)
149
+ path_to_key ||= SSHUtil.default_rsa_pub_key_path()
150
+
151
+ response, matched, matched_username = Account.add_key(path_to_key, false, name)
152
+
153
+ if matched
154
+ OsUtil.print("Provided SSH pub key has already been added.", :yellow)
155
+ elsif matched_username
156
+ OsUtil.print("User ('#{matched_username}') already exists.", :yellow)
157
+ else
158
+ Configurator.add_current_user_to_direct_access() if response.ok?
159
+ end
160
+
161
+ if response.ok? && response.data(:repoman_registration_error)
162
+ OsUtil.print("Warning: We were not able to register your key with remote catalog! #{response.data(:repoman_registration_error)}", :yellow)
163
+ end
164
+
165
+ response.ok? ? nil : response
166
+ end
167
+
168
+ desc "delete-ssh-key KEYPAIR-NAME [-y]","Deletes the named ssh key from your user account"
169
+ method_option :force, :aliases => '-y', :type => :boolean, :default => false
170
+ def delete_ssh_key(context_params)
171
+ name = context_params.retrieve_arguments([:option_1!],method_argument_names)
172
+
173
+ unless options.force?
174
+ is_go = Console.confirmation_prompt("Are you sure you want to delete SSH key '#{name}'"+"?")
175
+ return nil unless is_go
176
+ end
177
+
178
+ response = post rest_url("account/remove_user_direct_access"), { :username => name.chomp }
179
+ return response unless response.ok?
180
+
181
+ if response.ok? && response.data(:repoman_registration_error)
182
+ OsUtil.print("Warning: We were not able to unregister your key with remote catalog! #{response.data(:repoman_registration_error)}", :yellow)
183
+ end
184
+
185
+ OsUtil.print("SSH key '#{name}' removed successfully!", :yellow)
186
+ nil
187
+ end
188
+
189
+ desc "set-default-namespace NAMESPACE", "Sets default namespace for your user account"
190
+ def set_default_namespace(context_params)
191
+ default_namespace = context_params.retrieve_arguments([:option_1!],method_argument_names)
192
+ post_body = { :namespace => default_namespace.chomp }
193
+
194
+ response = post rest_url("account/set_default_namespace"), post_body
195
+ return response unless response.ok?
196
+
197
+ OsUtil.print("Your default namespace has been set to '#{default_namespace}'!", :yellow)
198
+ nil
199
+ end
200
+
201
+ desc "set-catalog-credentials", "Sets catalog credentials"
202
+ def set_catalog_credentials(context_params)
203
+ creds = Configurator.enter_catalog_credentials()
204
+
205
+ response = post rest_url("account/set_catalog_credentials"), { :username => creds[:username], :password => creds[:password], :validate => true }
206
+ return response unless response.ok?
207
+
208
+ OsUtil.print("Your catalog credentials have been set!", :yellow)
209
+ nil
210
+ end
211
+
212
+ desc "register-catalog-user", "Create your catalog user"
213
+ def register_catalog_user(context_params)
214
+ body_params = Shell::InteractiveWizard.interactive_user_input([
215
+ {:username => { :required => true} },
216
+ {:password => { :type => :password }},
217
+ {:repeat_password => { :type => :repeat_password }},
218
+ {:email => { :type => :email, :required => true }},
219
+ {:first_name => {}},
220
+ {:last_name => {}}
221
+ ])
222
+ OsUtil.print("Creating account please wait ...", :white)
223
+ response = post rest_url("account/register_catalog_account"), body_params
224
+
225
+ if response.ok?
226
+ OsUtil.print("You have successfully created catalog account!", :green)
227
+ if Console.confirmation_prompt_simple("Do you want to make this account active?")
228
+ response = post rest_url("account/set_catalog_credentials"), { :username => body_params[:username], :password => body_params[:password], :validate => true }
229
+ OsUtil.print("Catalog user '#{body_params[:username]}' is currently active user!", :green)
230
+ end
231
+ else
232
+ return response
233
+ end
234
+
235
+ nil
236
+ end
237
+
238
+ end
239
+ end
@@ -0,0 +1,356 @@
1
+ #
2
+ # Copyright (C) 2010-2016 dtk contributors
3
+ #
4
+ # This file is part of the dtk project.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ dtk_require_from_base("shell/status_monitor")
19
+ dtk_require_common_commands('thor/assembly_template')
20
+ module DTK::Client
21
+ class Assembly < CommandBaseThor
22
+ no_tasks do
23
+ include AssemblyTemplateMixin
24
+ end
25
+
26
+ def self.whoami()
27
+ return :assembly, "assembly/list", {:subtype => 'template'}
28
+ end
29
+
30
+ def self.get_assembly_template_id_for_service(assembly_template_name, service)
31
+ assembly_template_id = nil
32
+ # TODO: See with Rich if there is better way to resolve this
33
+ response = DTK::Client::CommandBaseThor.get_cached_response(:assembly, "assembly/list", {:subtype => 'template' })
34
+ # response = DTK::Client::CommandBaseThor.get_cached_response(:module, "service_module/list")
35
+
36
+ service_namespace = service.split(":").first
37
+ service_name = service.split(":").last
38
+
39
+ if response.ok?
40
+ unless response['data'].nil?
41
+ response['data'].each do |module_item|
42
+ if ("#{service_name.to_s}/#{assembly_template_name.to_s}" == (module_item['display_name']) && service_namespace == module_item['namespace'])
43
+ assembly_template_id = module_item['id']
44
+ break
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ raise DTK::Client::DtkError, "Illegal name (#{assembly_template_name}) for assembly." if assembly_template_id.nil?
51
+
52
+ return assembly_template_id
53
+ end
54
+
55
+ def self.get_assembly_template_name_for_service(assembly_template_id, service)
56
+ assembly_template_name = nil
57
+ # TODO: See with Rich if there is better way to resolve this
58
+ response = DTK::Client::CommandBaseThor.get_cached_response(:assembly, "assembly/list", {:subtype => 'template' })
59
+
60
+ if response.ok?
61
+ unless response['data'].nil?
62
+ response['data'].each do |module_item|
63
+ if assembly_template_id.to_i == module_item['id']
64
+ assembly_template_name = module_item['display_name'].gsub("#{service.to_s}::",'')
65
+ break
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ raise DTK::Client::DtkError, "Illegal name or id (#{assembly_template_id}) for assembly." if assembly_template_name.nil?
72
+ return assembly_template_name
73
+ end
74
+
75
+ def self.pretty_print_cols()
76
+ PPColumns.get(:assembly)
77
+ end
78
+
79
+
80
+ # List assembly templates for specific module
81
+ def self.validation_list(context_params)
82
+ if context_params.is_there_identifier?(:"service-module")
83
+ service_module_id = context_params.retrieve_arguments([:service_module_id!])
84
+ get_cached_response(:assembly, "service_module/list_assemblies", { :service_module_id => service_module_id })
85
+ else
86
+ get_cached_response(:assembly, "assembly/list", {:subtype => 'template' })
87
+ end
88
+ end
89
+
90
+ def self.assembly_list()
91
+ assembly_list = []
92
+ response = get_cached_response(:service, "assembly/list", {})
93
+ raise DTK::Client::DtkError, "Unable to retreive service list." unless (response.nil? || response.ok?)
94
+
95
+ if assemblies = response.data
96
+ assemblies.each do |assembly|
97
+ assembly_list << assembly["display_name"]
98
+ end
99
+ end
100
+
101
+ assembly_list
102
+ end
103
+
104
+ desc "ASSEMBLY-NAME/ID info", "Get information about given assembly."
105
+ method_option :list, :type => :boolean, :default => false
106
+ def info(context_params)
107
+ assembly_template_id = context_params.retrieve_arguments([:assembly_id!],method_argument_names)
108
+ data_type = :assembly_template
109
+
110
+ post_body = {
111
+ :assembly_id => assembly_template_id,
112
+ :subtype => 'template',
113
+ }
114
+
115
+ post rest_url("assembly/info"), post_body
116
+ end
117
+
118
+ desc "ASSEMBLY-NAME/ID list-nodes [--service SERVICE-NAME]", "List all nodes for given assembly."
119
+ method_option :list, :type => :boolean, :default => false
120
+ method_option "service",:aliases => "-s" ,
121
+ :type => :string,
122
+ :banner => "SERVICE-LIST-FILTER",
123
+ :desc => "Service list filter"
124
+ def list_nodes(context_params)
125
+ context_params.method_arguments = ["nodes"]
126
+ list(context_params)
127
+ end
128
+
129
+ desc "ASSEMBLY-NAME/ID list-components [--service SERVICE-NAME]", "List all components for given assembly."
130
+ method_option :list, :type => :boolean, :default => false
131
+ method_option "service",:aliases => "-s" ,
132
+ :type => :string,
133
+ :banner => "SERVICE-LIST-FILTER",
134
+ :desc => "Service list filter"
135
+ def list_components(context_params)
136
+ context_params.method_arguments = ["components"]
137
+ list(context_params)
138
+ end
139
+
140
+ # desc "[ASSEMBLY-TEMPLATE-NAME/ID] show [nodes|components|targets]", "List all nodes/components/targets for given assembly template."
141
+ #TODO: temporaily taking out target option
142
+ desc "list", "List all assemblies."
143
+ def list(context_params)
144
+ assembly_template_id, about, service_filter = context_params.retrieve_arguments([:assembly_id, :option_1, :option_1],method_argument_names)
145
+
146
+ if assembly_template_id.nil?
147
+
148
+ if options.service
149
+ service_id = options.service
150
+ context_params_for_service = DTK::Shell::ContextParams.new
151
+ context_params_for_service.add_context_to_params("service_module", "service_module", service_id)
152
+ context_params_for_service.method_arguments = ['assembly',"#{service_id}"]
153
+
154
+ response = DTK::Client::ContextRouter.routeTask("service_module", "list", context_params_for_service, @conn)
155
+ else
156
+ response = post rest_url("assembly/list"), {:subtype => 'template', :detail_level => 'nodes'}
157
+ data_type = :assembly_template
158
+ response.render_table(data_type) unless options.list?
159
+ return response
160
+ end
161
+
162
+ else
163
+
164
+ post_body = {
165
+ :subtype => 'template',
166
+ :assembly_id => assembly_template_id,
167
+ :about => about
168
+ }
169
+
170
+ case about
171
+ when 'nodes'
172
+ response = post rest_url("assembly/info_about"), post_body
173
+ data_type = :assembly_node_template
174
+ when 'components'
175
+ response = post rest_url("assembly/info_about"), post_body
176
+ data_type = :component
177
+ # when 'attributes'
178
+ # response = post rest_url("assembly/info_about"), post_body
179
+ # data_type = :attribute
180
+ else
181
+ raise_validation_error_method_usage('list')
182
+ end
183
+
184
+ response.render_table(data_type) unless options.list?
185
+
186
+ return response
187
+ end
188
+ end
189
+
190
+ desc "ASSEMBLY-NAME/ID list-settings", "List all settings for given assembly."
191
+ def list_settings(context_params)
192
+ assembly_template_id = context_params.retrieve_arguments([:assembly_id!],method_argument_names)
193
+
194
+ post_body = {
195
+ :assembly_id => assembly_template_id
196
+ }
197
+
198
+ response = post rest_url("assembly/list_settings"), post_body
199
+ response.render_table(:service_setting) unless options.list?
200
+
201
+ response
202
+ end
203
+
204
+ desc "ASSEMBLY-NAME/ID stage-target [INSTANCE-NAME] [-t PARENT-SERVICE-INSTANCE-NAME/ID] [-v VERSION] [--no-auto-complete]", "Stage assembly as target instance."
205
+ method_option :settings, :type => :string, :aliases => '-s'
206
+ method_option :no_auto_complete, :type => :boolean, :default => false, :aliases => '--no-ac'
207
+ method_option :parent_service, :type => :string, :aliases => '-t'
208
+ version_method_option
209
+ #hidden options
210
+ method_option "instance-bindings", :type => :string
211
+ method_option :is_target, :type => :boolean, :default => true
212
+ def stage_target(context_params)
213
+ end
214
+
215
+
216
+ desc "ASSEMBLY-NAME/ID stage [INSTANCE-NAME] [-t PARENT-SERVICE-INSTANCE-NAME/ID] [-v VERSION] [--no-auto-complete]", "Stage assembly in target."
217
+ method_option :settings, :type => :string, :aliases => '-s'
218
+ method_option :no_auto_complete, :type => :boolean, :default => false, :aliases => '--no-ac'
219
+ method_option :parent_service, :type => :string, :aliases => '-t'
220
+ version_method_option
221
+ method_option "instance-bindings", :type => :string
222
+ def stage(context_params)
223
+ assembly_template_id, service_module_id, name = context_params.retrieve_arguments([:assembly_id!, :service_module_id, :option_1],method_argument_names)
224
+ post_body = {
225
+ :assembly_id => assembly_template_id
226
+ }
227
+
228
+ # special case when we need service module id
229
+ post_body[:service_module_id] = service_module_id if context_params.pure_cli_mode
230
+
231
+ # using this to make sure cache will be invalidated after new assembly is created from other commands e.g.
232
+ # 'assembly-create', 'install' etc.
233
+ @@invalidate_map << :assembly
234
+
235
+ assembly_template_name = get_assembly_name(assembly_template_id)
236
+ if assembly_template_name
237
+ assembly_template_name.gsub!(/(::)|(\/)/,'-')
238
+ end
239
+
240
+ instance_bindings = options["instance-bindings"]
241
+ settings = parse_service_settings(options["settings"])
242
+ node_size = options.node_size
243
+ os_type = options.os_type
244
+ assembly_list = Assembly.assembly_list()
245
+
246
+ if name
247
+ raise DTK::Client::DtkValidationError, "Unable to stage service with name '#{name}'. Service with specified name exists already!" if assembly_list.include?(name)
248
+ else
249
+ name = get_assembly_stage_name(assembly_list,assembly_template_name)
250
+ end
251
+
252
+ post_body.merge!(:name => name) if name
253
+ post_body.merge!(:instance_bindings => instance_bindings) if instance_bindings
254
+ post_body.merge!(:settings_json_form => JSON.generate(settings)) if settings
255
+ post_body.merge!(:node_size => node_size) if node_size
256
+ post_body.merge!(:os_type => os_type) if os_type
257
+
258
+ response = post rest_url("assembly/stage"), post_body
259
+ return response unless response.ok?
260
+ # when changing context send request for getting latest assemblies instead of getting from cache
261
+ @@invalidate_map << :service
262
+ @@invalidate_map << :assembly
263
+
264
+ return response
265
+ end
266
+
267
+ desc "ASSEMBLY-NAME/ID deploy-target [INSTANCE-NAME] [-v VERSION] [--no-auto-complete] [--stream-results]", "Deploy assembly as target instance."
268
+ method_option 'stream-results', :aliases => '-s', :type => :boolean, :default => false, :desc => "Stream results"
269
+ method_option :no_auto_complete, :type => :boolean, :default => false, :aliases => '--no-ac'
270
+ version_method_option
271
+ #hidden options
272
+ method_option "instance-bindings", :type => :string
273
+ method_option :is_target, :type => :boolean, :default => true
274
+ # method_option :settings, :type => :string, :aliases => '-s'
275
+ def deploy_target(context_params)
276
+ end
277
+
278
+ desc "ASSEMBLY-NAME/ID deploy [INSTANCE-NAME] [-t PARENT-SERVICE-INSTANCE-NAME/ID] [-v VERSION] [--no-auto-complete] [--stream-results]", "Deploy assembly in target."
279
+ method_option 'stream-results', :aliases => '-s', :type => :boolean, :default => false, :desc => "Stream results"
280
+ method_option :no_auto_complete, :type => :boolean, :default => false, :aliases => '--no-ac'
281
+ method_option :parent_service, :type => :string, :aliases => '-t'
282
+ version_method_option
283
+ #hidden options
284
+ method_option "instance-bindings", :type => :string
285
+ def deploy(context_params)
286
+ context_params.forward_options(options)
287
+ assembly_template_id, service_module_id, name = context_params.retrieve_arguments([:assembly_id!, :service_module_id, :option_1],method_argument_names)
288
+ post_body = {
289
+ :assembly_id => assembly_template_id
290
+ }
291
+
292
+ # special case when we need service module id
293
+ post_body[:service_module_id] = service_module_id if context_params.pure_cli_mode
294
+
295
+ if commit_msg = options["commit_msg"]
296
+ post_body.merge!(:commit_msg => commit_msg)
297
+ end
298
+
299
+ # using this to make sure cache will be invalidated after new assembly is created from other commands e.g.
300
+ # 'assembly-create', 'install' etc.
301
+ @@invalidate_map << :assembly
302
+
303
+ assembly_template_name = get_assembly_name(assembly_template_id)
304
+ if assembly_template_name
305
+ assembly_template_name.gsub!(/(::)|(\/)/,'-')
306
+ end
307
+
308
+ # we check current options and forwarded options (from deploy method)
309
+ instance_bindings = options["instance-bindings"]
310
+ settings = parse_service_settings(options["settings"])
311
+ assembly_list = Assembly.assembly_list()
312
+
313
+ if name
314
+ raise DTK::Client::DtkValidationError, "Unable to deploy service with name '#{name}'. Service with specified name exists already!" if assembly_list.include?(name)
315
+ else
316
+ name = get_assembly_stage_name(assembly_list,assembly_template_name)
317
+ end
318
+
319
+ post_body.merge!(:name => name) if name
320
+ post_body.merge!(:instance_bindings => instance_bindings) if instance_bindings
321
+ post_body.merge!(:settings_json_form => JSON.generate(settings)) if settings
322
+
323
+ response = post rest_url("assembly/deploy"), post_body
324
+ return response unless response.ok?
325
+ # when changing context send request for getting latest assemblies instead of getting from cache
326
+ @@invalidate_map << :service
327
+ @@invalidate_map << :assembly
328
+ response
329
+ end
330
+
331
+
332
+ desc "delete ASSEMBLY-ID", "Delete assembly"
333
+ method_option :force, :aliases => '-y', :type => :boolean, :default => false
334
+ def delete(context_params)
335
+ assembly_template_id = context_params.retrieve_arguments([:option_1!],method_argument_names)
336
+ unless options.force?
337
+ # Ask user if really want to delete assembly-template, if not then return to dtk-shell without deleting
338
+ return unless Console.confirmation_prompt("Are you sure you want to delete assembly '#{assembly_template_id}'"+"?")
339
+ end
340
+
341
+ post_body = {
342
+ :assembly_id => assembly_template_id,
343
+ :subtype => :template
344
+ }
345
+ response = post rest_url("assembly/delete"), post_body
346
+
347
+ # when changing context send request for getting latest assemblies instead of getting from cache
348
+ @@invalidate_map << :assembly
349
+ return response unless response.ok?
350
+ module_name,branch = response.data(:module_name,:workspace_branch)
351
+ response = Helper(:git_repo).pull_changes?(:service_module,module_name,:local_branch => branch)
352
+ return response unless response.ok?()
353
+ Response::Ok.new()
354
+ end
355
+ end
356
+ end