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,125 @@
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
+ # TODO: Marked for removal [Haris]
19
+ module DTK::Client
20
+
21
+ class Library < CommandBaseThor
22
+
23
+ def self.pretty_print_cols()
24
+ PPColumns.get(:library)
25
+ end
26
+
27
+ def self.whoami()
28
+ return :library, "library/list", nil
29
+ end
30
+
31
+ desc "[LIBRARY ID/NAME] info","Info for given library based on specified identifier."
32
+ def info(context_params)
33
+ library_id = context_params.retrieve_arguments([:library_id],method_argument_names)
34
+ not_implemented
35
+ end
36
+
37
+ desc "LIBRARY ID/NAME list-nodes","Show nodes associated with library"
38
+ def list_nodes(context_params)
39
+ context_params.method_arguments = ["nodes"]
40
+ list(context_params)
41
+ end
42
+
43
+ desc "LIBRARY ID/NAME list-components","Show components associated with library"
44
+ def list_components(context_params)
45
+ context_params.method_arguments = ["components"]
46
+ list(context_params)
47
+ end
48
+
49
+ desc "LIBRARY ID/NAME list-assemblies","Show assemblies associated with library"
50
+ def list_assemblies(context_params)
51
+ context_params.method_arguments = ["assemblies"]
52
+ list(context_params)
53
+ end
54
+
55
+ desc "list","Show nodes, components, or assemblies associated with library"
56
+ def list(context_params)
57
+ library_id, about = context_params.retrieve_arguments([:library_id, :option_1],method_argument_names||="")
58
+ if library_id.nil?
59
+ search_hash = SearchHash.new()
60
+ search_hash.cols = pretty_print_cols()
61
+ response = post rest_url("library/list"), search_hash.post_body_hash
62
+ response.render_table(:library)
63
+ else
64
+ # sets data type to be used when printing table
65
+ case about
66
+ when "assemblies"
67
+ data_type = :assembly_template
68
+ when "nodes"
69
+ data_type = :node_template
70
+ when "components"
71
+ data_type = :component
72
+ else
73
+ raise_validation_error_method_usage('list')
74
+ end
75
+
76
+ post_body = {
77
+ :library_id => library_id,
78
+ :about => about
79
+ }
80
+ response = post rest_url("library/info_about"), post_body
81
+ response.render_table(data_type)
82
+ end
83
+ end
84
+
85
+ desc "[LIBRARY ID/NAME] import-service-module REMOTE-SERVICE-MODULE[,...]", "Import remote service module into library"
86
+ def import_service_module(context_params)
87
+ library_id, service_modules = context_params.retrieve_arguments([:library_id, :option_1!],method_argument_names)
88
+ post_body = {
89
+ :remote_module_name => service_modules,
90
+ :rsa_pub_key => SSHUtil.rsa_pub_key_content()
91
+ }
92
+ post_body.merge!(:library_id => library_id) if library_id
93
+
94
+ post rest_url("service_module/import"), post_body
95
+ end
96
+
97
+ desc "[LIBRARY ID/NAME] create-service-component SERVICE-MODULE-NAME", "Create an empty service module in library"
98
+ def create(context_params)
99
+ library_id, module_name = context_params.retrieve_arguments([:library_id, :option_1!],method_argument_names)
100
+ post_body = {
101
+ :module_name => module_name
102
+ }
103
+ post_body.merge!(:library_id => library_id) if library_id
104
+ response = post rest_url("service_module/create"), post_body
105
+ # when changing context send request for getting latest libraries instead of getting from cache
106
+ @@invalidate_map << :library
107
+
108
+ return response
109
+ end
110
+
111
+ desc "[LIBRARY ID/NAME] delete-service-component COMPONENT-MODULE-NAME","Delete component module and all items contained in it"
112
+ def delete(context_params)
113
+ library_id, component_module_id = context_params.retrieve_arguments([:library_id, :option_1!],method_argument_names)
114
+ post_body = {
115
+ :component_module_id => component_module_id
116
+ }
117
+ post_body.merge!(:library_id => library_id) if library_id
118
+ response = post rest_url("component_module/delete"), post_body
119
+ # when changing context send request for getting latest libraries instead of getting from cache
120
+ @@invalidate_map << :library
121
+
122
+ return response
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,504 @@
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('task_status')
19
+ dtk_require_common_commands('thor/node')
20
+ dtk_require_common_commands('thor/set_required_attributes')
21
+ dtk_require_common_commands('thor/assembly_workspace')
22
+
23
+ module DTK::Client
24
+ class Node < CommandBaseThor
25
+
26
+ include AssemblyWorkspaceMixin
27
+ include NodeMixin
28
+
29
+ no_tasks do
30
+ include TaskStatusMixin
31
+ include SetRequiredParamsMixin
32
+ end
33
+
34
+ def self.pretty_print_cols()
35
+ PPColumns.get(:node)
36
+ end
37
+
38
+ def self.valid_children()
39
+ # [:component, :utils]
40
+ [:utils]
41
+ end
42
+
43
+ def self.multi_context_children()
44
+ [:utils]
45
+ end
46
+
47
+ def self.all_children()
48
+ [:component, :attribute]
49
+ # [:node]
50
+ end
51
+
52
+ # using extended_context when we want to use autocomplete from other context
53
+ # e.g. we are in assembly/apache context and want to create-component we will use extended context to add
54
+ # component-templates to autocomplete
55
+ def self.extended_context()
56
+ {
57
+ :context => {
58
+ },
59
+ :command => {
60
+ :add_component => {
61
+ :endpoint => "component_template",
62
+ :url => "component/list",
63
+ :opts => {:subtype=>"template", :ignore => "test_module", :hide_assembly_cmps => "true"}
64
+ },
65
+ :delete_component => {
66
+ :endpoint => "assembly",
67
+ :url => "assembly/info_about",
68
+ :opts => {:subtype=>"instance", :about=>"components"}
69
+ }
70
+ }
71
+ }
72
+ end
73
+
74
+ def self.valid_child?(name_of_sub_context)
75
+ return Node.valid_children().include?(name_of_sub_context.to_sym)
76
+ end
77
+
78
+ def self.validation_list(context_params)
79
+ assembly_id, workspace_id = context_params.retrieve_arguments([:service_id, :workspace_id])
80
+
81
+ if (assembly_id || workspace_id)
82
+ # if assebmly_id is present we're loading nodes filtered by assembly_id
83
+ post_body = {
84
+ :assembly_id => assembly_id||workspace_id,
85
+ :subtype => 'instance',
86
+ :about => 'nodes',
87
+ :filter => nil
88
+ }
89
+
90
+ response = get_cached_response(:service_node, "assembly/info_about", post_body)
91
+ else
92
+ # otherwise, load all nodes
93
+ response = get_cached_response(:node, "node/list", nil)
94
+ end
95
+
96
+ return response
97
+ end
98
+
99
+ def self.override_allowed_methods()
100
+ return DTK::Shell::OverrideTasks.new({
101
+ :command_only => {
102
+ :utils => [
103
+ ['get-netstats',"get-netstats","# Get netstats."],
104
+ ['get-ps',"get-ps [--filter PATTERN]","# Get ps."]
105
+ ]
106
+ }
107
+ })
108
+ end
109
+
110
+ desc "NODE-NAME/ID info","Info about node"
111
+ def info(context_params)
112
+ node_id = context_params.retrieve_arguments([:node_id!],method_argument_names)
113
+ post_body = {
114
+ :node_id => node_id,
115
+ :subtype => 'instance',
116
+ }
117
+
118
+ post rest_url("node/info"), post_body
119
+ end
120
+
121
+ desc "NODE-NAME/ID ssh [LINUX-LOGIN-USER] [-i PATH-TO-PEM]","SSH into node."
122
+ method_option "--identity-file",:aliases => '-i',:type => :string, :desc => "Identity-File used for connection, if not provided default is used", :banner => "IDENTITY-FILE"
123
+ def ssh(context_params)
124
+ if OsUtil.is_windows?
125
+ puts "[NOTICE] SSH functionality is currenly not supported on Windows."
126
+ return
127
+ end
128
+
129
+ node_id, login_user = context_params.retrieve_arguments([:node_id!,:option_1],method_argument_names)
130
+
131
+ if identity_file_location = options['identity-file']
132
+ unless File.exists?(identity_file_location)
133
+ raise DtkError, "Not able to find identity file, '#{identity_file_location}'"
134
+ end
135
+ elsif default_identity_file = OsUtil.dtk_identity_file_location()
136
+ if File.exists?(default_identity_file)
137
+ identity_file_location = default_identity_file
138
+ end
139
+ end
140
+
141
+ response = get_node_info_for_ssh_login(node_id, context_params)
142
+ return response unless response.ok?
143
+
144
+ unless public_dns = response.data(:public_dns)
145
+ raise DtkError, "Not able to resolve instance address, has instance been stopped?"
146
+ end
147
+
148
+ unless login_user ||= response.data(:default_login_user)
149
+ raise DtkError, "Retry command with a specfic login user (a default login user could not be computed)"
150
+ end
151
+
152
+ connection_string = "#{login_user}@#{public_dns}"
153
+
154
+ ssh_command =
155
+ if identity_file_location
156
+ # provided PEM key
157
+ "ssh -o \"StrictHostKeyChecking no\" -o \"UserKnownHostsFile /dev/null\" -i #{identity_file_location} #{connection_string}"
158
+ elsif SSHUtil.ssh_reachable?(login_user, public_dns)
159
+ # it has PUB key access
160
+ "ssh -o \"StrictHostKeyChecking no\" -o \"UserKnownHostsFile /dev/null\" #{connection_string}"
161
+ end
162
+
163
+ unless ssh_command
164
+ raise DtkError, "No public key access or PEM provided, please grant access or provide valid PEM key"
165
+ end
166
+
167
+ OsUtil.print("You are entering SSH terminal (#{connection_string}) ...", :yellow)
168
+ Kernel.system(ssh_command)
169
+ OsUtil.print("You are leaving SSH terminal, and returning to DTK Shell ...", :yellow)
170
+ end
171
+
172
+ desc "NODE-NAME/ID list-components","List components that are on the node instance."
173
+ method_option :list, :type => :boolean, :default => false
174
+ def list_components(context_params)
175
+ context_params.method_arguments = ["components"]
176
+ list(context_params)
177
+ end
178
+
179
+ desc "NODE-NAME/ID list-attributes","List attributes that are on the node instance."
180
+ method_option :list, :type => :boolean, :default => false
181
+ def list_attributes(context_params)
182
+ context_params.method_arguments = ["attributes"]
183
+ list(context_params)
184
+ end
185
+
186
+ desc "list","List components that are on the node instance."
187
+ method_option :list, :type => :boolean, :default => false
188
+ def list(context_params)
189
+ node_id, about = context_params.retrieve_arguments([:node_id,:option_1],method_argument_names)
190
+
191
+ if node_id.nil?
192
+ response = post rest_url("node/list")
193
+
194
+ response.render_table(:node) unless options.list?
195
+ return response
196
+ else
197
+
198
+ post_body = {
199
+ :node_id => node_id,
200
+ :subtype => 'instance',
201
+ :about => about
202
+ }
203
+
204
+ case about
205
+ when "components"
206
+ data_type = :component
207
+ when "attributes"
208
+ data_type = :attribute
209
+ else
210
+ raise_validation_error_method_usage('list')
211
+ end
212
+
213
+ response = post rest_url("node/info_about"), post_body
214
+ return response.render_table(data_type)
215
+ end
216
+ end
217
+
218
+ desc "NODE-NAME/ID set ATTRIBUTE-ID VALUE", "Set node group attribute value"
219
+ def set(context_params)
220
+ node_id, attr_id, value = context_params.retrieve_arguments([:node_id!, :option_1!, :option_2!],method_argument_names)
221
+ post_body = {
222
+ :node_id => node_id,
223
+ :pattern => attr_id,
224
+ :value => value
225
+ }
226
+ post rest_url("node/set_attributes"), post_body
227
+ end
228
+
229
+ desc "NODE-NAME/ID set-required-attributes", "Interactive dialog to set required attributes that are not currently set"
230
+ def set_required_attributes(context_params)
231
+ node_id = context_params.retrieve_arguments([:node_id!],method_argument_names)
232
+ set_required_attributes_aux(node_id,:node)
233
+ end
234
+
235
+ # desc "NODE-NAME/ID create-component COMPONENT-TEMPLATE-NAME/ID [-v VERSION]", "Add component template to node"
236
+ # version_method_option
237
+ desc "NODE-NAME/ID add-component COMPONENT-TEMPLATE-NAME/ID", "Add component template to node"
238
+ def add_component(context_params)
239
+ node_id,component_template_id = context_params.retrieve_arguments([:node_id!, :option_1!],method_argument_names)
240
+ post_body = {
241
+ :node_id => node_id,
242
+ :component_template_name => component_template_id
243
+ }
244
+ post_body.merge!(:version => options[:version]) if options[:version]
245
+
246
+ response = post rest_url("node/add_component"), post_body
247
+ return response unless response.ok?
248
+
249
+ @@invalidate_map << :node
250
+ return response
251
+ end
252
+
253
+ desc "NODE-NAME/ID delete-component COMPONENT-ID [-y]", "Delete component from node"
254
+ method_option :force, :aliases => '-y', :type => :boolean, :default => false
255
+ def delete_component(context_params)
256
+ node_id,component_id = context_params.retrieve_arguments([:node_id!, :option_1!],method_argument_names)
257
+
258
+ unless options.force?
259
+ return unless Console.confirmation_prompt("Are you sure you want to delete component '#{component_id}'"+'?')
260
+ end
261
+
262
+ post_body = {
263
+ :node_id => node_id,
264
+ :component_id => component_id
265
+ }
266
+ post rest_url("node/delete_component"), post_body
267
+ end
268
+
269
+ desc "NODE-NAME/ID converge [-m COMMIT-MSG]", "Converges service instance"
270
+ method_option "commit_msg",:aliases => "-m" ,
271
+ :type => :string,
272
+ :banner => "COMMIT-MSG",
273
+ :desc => "Commit message"
274
+ def converge(context_params)
275
+ node_id = context_params.retrieve_arguments([:node_id!],method_argument_names)
276
+ # create task
277
+ post_body = {
278
+ :node_id => node_id
279
+ }
280
+
281
+ response = post rest_url("node/find_violations"), post_body
282
+ return response unless response.ok?
283
+ if response.data and response.data.size > 0
284
+ #TODO: may not directly print here; isntead use a lower level fn
285
+ error_message = "The following violations were found; they must be corrected before the node can be converged"
286
+ OsUtil.print(error_message, :red)
287
+ return response.render_table(:violation)
288
+ end
289
+
290
+ post_body.merge!(:commit_msg => options.commit_msg) if options.commit_msg
291
+
292
+ response = post rest_url("node/create_task"), post_body
293
+ return response unless response.ok?
294
+
295
+ # execute task
296
+ task_id = response.data(:task_id)
297
+ post rest_url("task/execute"), "task_id" => task_id
298
+ end
299
+
300
+ desc "NODE-NAME/ID task-status [--wait]", "Task status of running or last service task"
301
+ method_option :wait, :type => :boolean, :default => false
302
+ def task_status(context_params)
303
+ node_id = context_params.retrieve_arguments([:node_id!],method_argument_names)
304
+ task_status_aux(node_id,:node,:wait => options.wait?)
305
+ end
306
+
307
+ desc "NODE-NAME/ID list-task-info", "Task status details of running or last service task"
308
+ def list_task_info(context_params)
309
+ node_id = context_params.retrieve_arguments([:node_id!],method_argument_names)
310
+ list_task_info_aux("node", node_id)
311
+ end
312
+
313
+ desc "NODE-NAME/ID cancel-task TASK_ID", "Cancels task."
314
+ def cancel_task(context_params)
315
+ task_id = context_params.retrieve_arguments([:option_1!],method_argument_names)
316
+ cancel_task_aux(task_id)
317
+ end
318
+
319
+ # desc "list-smoketests ASSEMBLY-ID","List smoketests on asssembly"
320
+ desc "destroy NODE-ID", "Delete and destroy (terminate) node"
321
+ method_option :force, :aliases => '-y', :type => :boolean, :default => false
322
+ def destroy(context_params)
323
+ node_id = context_params.retrieve_arguments([:option_1!],method_argument_names)
324
+ post_body = {
325
+ :node_id => node_id
326
+ }
327
+ unless options.force?
328
+ # Ask user if really want to delete and destroy, if not then return to dtk-shell without deleting
329
+ return unless Console.confirmation_prompt("Are you sure you want to destroy and delete node '#{node_id}'"+"?")
330
+ end
331
+
332
+ response = post rest_url("node/destroy_and_delete"), post_body
333
+ @@invalidate_map << :node
334
+
335
+ return response
336
+ end
337
+
338
+ desc "NODE-NAME/ID op-status", "Get node operational status"
339
+ def op_status(context_params)
340
+ node_id = context_params.retrieve_arguments([:node_id!],method_argument_names)
341
+ post rest_url("node/get_op_status"), :node_id => node_id
342
+ end
343
+
344
+ desc "NODE-NAME/ID start", "Start node instance."
345
+ def start(context_params)
346
+ node_id = context_params.retrieve_arguments([:node_id!],method_argument_names)
347
+ #TODO: Rich: took this out; think it is a bug
348
+ #assembly_id,node_id = get_assembly_and_node_id(context_params)
349
+
350
+ node_start(node_id)
351
+ end
352
+
353
+ desc "NODE-NAME/ID stop", "Stop node instance."
354
+ def stop(context_params)
355
+ node_id = context_params.retrieve_arguments([:node_id!],method_argument_names)
356
+ # Retrieving assembly_id to stop a node.. TODO create server side method that takes only node id
357
+ #TODO: Rich: took this out; think it is a bug
358
+ #assembly_id, node_id = get_assembly_and_node_id(context_params)
359
+
360
+ node_stop(node_id)
361
+ end
362
+
363
+ desc "HIDE_FROM_BASE get-netstats", "Get netstats"
364
+ def get_netstats(context_params)
365
+ node_id = context_params.retrieve_arguments([:node_id!],method_argument_names)
366
+
367
+ post_body = {
368
+ :node_id => node_id
369
+ }
370
+
371
+ response = post(rest_url("node/initiate_get_netstats"), post_body)
372
+ return response unless response.ok?
373
+
374
+ action_results_id = response.data(:action_results_id)
375
+ end_loop, response, count, ret_only_if_complete = false, nil, 0, true
376
+
377
+ until end_loop do
378
+ post_body = {
379
+ :action_results_id => action_results_id,
380
+ :return_only_if_complete => ret_only_if_complete,
381
+ :disable_post_processing => false
382
+ }
383
+ response = post(rest_url("node/get_action_results"),post_body)
384
+ count += 1
385
+ if count > GETNETSTATSTRIES or response.data(:is_complete)
386
+ end_loop = true
387
+ else
388
+ #last time in loop return whetever is teher
389
+ if count == GETNETSTATSTRIES
390
+ ret_only_if_complete = false
391
+ end
392
+ sleep GETNETSTATSSLEEP
393
+ end
394
+ end
395
+
396
+ #TODO: needed better way to render what is one of teh feileds which is any array (:results in this case)
397
+ response.set_data(*response.data(:results))
398
+ response.render_table(:netstat_data)
399
+ end
400
+
401
+ GETNETSTATSTRIES = 6
402
+ GETNETSTATSSLEEP = 0.5
403
+
404
+ desc "HIDE_FROM_BASE get-ps [FILTER]", "Get ps"
405
+ def get_ps(context_params)
406
+ node_id, filter_pattern = context_params.retrieve_arguments([:node_id!, :option_1],method_argument_names)
407
+
408
+ post_body = {
409
+ :node_id => node_id
410
+ }
411
+
412
+ response = post(rest_url("node/initiate_get_ps"), post_body)
413
+ return response unless response.ok?
414
+
415
+ action_results_id = response.data(:action_results_id)
416
+ end_loop, response, count, ret_only_if_complete = false, nil, 0, true
417
+
418
+ until end_loop do
419
+ post_body = {
420
+ :action_results_id => action_results_id,
421
+ :return_only_if_complete => ret_only_if_complete,
422
+ :disable_post_processing => true
423
+ }
424
+ response = post(rest_url("node/get_action_results"),post_body)
425
+ count += 1
426
+ if count > GETPSTRIES or response.data(:is_complete)
427
+ end_loop = true
428
+ else
429
+ #last time in loop return whetever is teher
430
+ if count == GETPSTRIES
431
+ ret_only_if_complete = false
432
+ end
433
+ sleep GETPSSLEEP
434
+ end
435
+ end
436
+
437
+ response_processed = response.data['results'].values.flatten
438
+ response_processed.reject! {|r| !r.to_s.include?(filter_pattern)} unless filter_pattern.nil?
439
+
440
+ #TODO: needed better way to render what is one of teh feileds which is any array (:results in this case)
441
+ response.set_data(*response_processed)
442
+ response.render_table(:ps_data)
443
+ end
444
+ GETPSTRIES = 6
445
+ GETPSSLEEP = 0.5
446
+
447
+ no_tasks do
448
+ def node_start(node_id)
449
+ post_body = {
450
+ :node_id => node_id
451
+ }
452
+
453
+ # we expect action result ID
454
+ response = post rest_url("node/start"), post_body
455
+ return response if response.data(:errors)
456
+
457
+ action_result_id = response.data(:action_results_id)
458
+
459
+ # bigger number here due to possibilty of multiple nodes
460
+ # taking too much time to be ready
461
+ 18.times do
462
+ action_body = {
463
+ :action_results_id => action_result_id,
464
+ :using_simple_queue => true
465
+ }
466
+ response = post(rest_url("assembly/get_action_results"),action_body)
467
+
468
+ if response['errors']
469
+ return response
470
+ end
471
+
472
+ break unless response.data(:result).nil?
473
+
474
+ puts "Waiting for nodes to be ready ..."
475
+ sleep(10)
476
+ end
477
+
478
+ if response.data(:result).nil?
479
+ raise DtkError, "Server seems to be taking too long to start node(s)."
480
+ end
481
+
482
+ task_id = response.data(:result)['task_id']
483
+ post(rest_url("task/execute"), "task_id" => task_id)
484
+ end
485
+
486
+ def node_stop(node_id)
487
+ post_body = {
488
+ :node_id => node_id
489
+ }
490
+
491
+ post rest_url("node/stop"), post_body
492
+ end
493
+ # get numeric ID, from possible name id
494
+ def get_assembly_and_node_id(context_params)
495
+ response = info(context_params)
496
+ unless response.ok?
497
+ raise DtkError, "Unable to retrive node information, please try again."
498
+ end
499
+
500
+ return response.data(:assembly_id), response.data(:id)
501
+ end
502
+ end
503
+ end
504
+ end