dtk-shell 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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