dtk-client 0.5.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +5 -0
  3. data/Gemfile_dev +12 -0
  4. data/README.md +78 -0
  5. data/bin/dtk +54 -0
  6. data/bin/dtk-shell +15 -0
  7. data/dtk-client.gemspec +49 -0
  8. data/lib/auxiliary.rb +13 -0
  9. data/lib/bundler_monkey_patch.rb +9 -0
  10. data/lib/client.rb +48 -0
  11. data/lib/command_helper.rb +16 -0
  12. data/lib/command_helpers/git_repo.rb +391 -0
  13. data/lib/command_helpers/jenkins_client/config_xml.rb +271 -0
  14. data/lib/command_helpers/jenkins_client.rb +91 -0
  15. data/lib/command_helpers/service_importer.rb +99 -0
  16. data/lib/command_helpers/service_link.rb +18 -0
  17. data/lib/command_helpers/ssh_processing.rb +43 -0
  18. data/lib/commands/common/thor/assembly_workspace.rb +1089 -0
  19. data/lib/commands/common/thor/clone.rb +39 -0
  20. data/lib/commands/common/thor/common.rb +34 -0
  21. data/lib/commands/common/thor/edit.rb +168 -0
  22. data/lib/commands/common/thor/list_diffs.rb +84 -0
  23. data/lib/commands/common/thor/pull_clone_changes.rb +11 -0
  24. data/lib/commands/common/thor/pull_from_remote.rb +99 -0
  25. data/lib/commands/common/thor/purge_clone.rb +26 -0
  26. data/lib/commands/common/thor/push_clone_changes.rb +45 -0
  27. data/lib/commands/common/thor/push_to_remote.rb +45 -0
  28. data/lib/commands/common/thor/reparse.rb +36 -0
  29. data/lib/commands/common/thor/set_required_params.rb +29 -0
  30. data/lib/commands/common/thor/task_status.rb +81 -0
  31. data/lib/commands/thor/account.rb +213 -0
  32. data/lib/commands/thor/assembly.rb +329 -0
  33. data/lib/commands/thor/attribute.rb +62 -0
  34. data/lib/commands/thor/component.rb +52 -0
  35. data/lib/commands/thor/component_module.rb +829 -0
  36. data/lib/commands/thor/component_template.rb +153 -0
  37. data/lib/commands/thor/dependency.rb +18 -0
  38. data/lib/commands/thor/developer.rb +105 -0
  39. data/lib/commands/thor/dtk.rb +117 -0
  40. data/lib/commands/thor/library.rb +107 -0
  41. data/lib/commands/thor/node.rb +411 -0
  42. data/lib/commands/thor/node_group.rb +211 -0
  43. data/lib/commands/thor/node_template.rb +88 -0
  44. data/lib/commands/thor/project.rb +17 -0
  45. data/lib/commands/thor/provider.rb +155 -0
  46. data/lib/commands/thor/repo.rb +35 -0
  47. data/lib/commands/thor/service.rb +656 -0
  48. data/lib/commands/thor/service_module.rb +806 -0
  49. data/lib/commands/thor/state_change.rb +10 -0
  50. data/lib/commands/thor/target.rb +94 -0
  51. data/lib/commands/thor/task.rb +100 -0
  52. data/lib/commands/thor/utils.rb +4 -0
  53. data/lib/commands/thor/workspace.rb +437 -0
  54. data/lib/commands.rb +40 -0
  55. data/lib/config/cacert.pem +3785 -0
  56. data/lib/config/client.conf.header +18 -0
  57. data/lib/config/configuration.rb +82 -0
  58. data/lib/config/default.conf +14 -0
  59. data/lib/config/disk_cacher.rb +60 -0
  60. data/lib/configurator.rb +92 -0
  61. data/lib/context_router.rb +23 -0
  62. data/lib/core.rb +460 -0
  63. data/lib/domain/git_adapter.rb +221 -0
  64. data/lib/domain/response.rb +234 -0
  65. data/lib/dtk-client/version.rb +3 -0
  66. data/lib/dtk_constants.rb +23 -0
  67. data/lib/dtk_logger.rb +96 -0
  68. data/lib/error.rb +74 -0
  69. data/lib/git-logs/git.log +0 -0
  70. data/lib/parser/adapters/option_parser.rb +53 -0
  71. data/lib/parser/adapters/thor/common_option_defs.rb +12 -0
  72. data/lib/parser/adapters/thor.rb +509 -0
  73. data/lib/require_first.rb +87 -0
  74. data/lib/search_hash.rb +27 -0
  75. data/lib/shell/context.rb +975 -0
  76. data/lib/shell/context_aux.rb +29 -0
  77. data/lib/shell/domain.rb +447 -0
  78. data/lib/shell/header_shell.rb +27 -0
  79. data/lib/shell/help_monkey_patch.rb +221 -0
  80. data/lib/shell/interactive_wizard.rb +233 -0
  81. data/lib/shell/parse_monkey_patch.rb +22 -0
  82. data/lib/shell/status_monitor.rb +105 -0
  83. data/lib/shell.rb +219 -0
  84. data/lib/util/console.rb +143 -0
  85. data/lib/util/dtk_puppet.rb +46 -0
  86. data/lib/util/os_util.rb +265 -0
  87. data/lib/view_processor/augmented_simple_list.rb +27 -0
  88. data/lib/view_processor/hash_pretty_print.rb +106 -0
  89. data/lib/view_processor/simple_list.rb +139 -0
  90. data/lib/view_processor/table_print.rb +277 -0
  91. data/lib/view_processor.rb +112 -0
  92. data/puppet/manifests/init.pp +72 -0
  93. data/puppet/manifests/params.pp +16 -0
  94. data/puppet/r8meta.puppet.yml +18 -0
  95. data/puppet/templates/bash_profile.erb +2 -0
  96. data/puppet/templates/client.conf.erb +1 -0
  97. data/puppet/templates/dtkclient.erb +2 -0
  98. data/spec/assembly_spec.rb +50 -0
  99. data/spec/assembly_template_spec.rb +51 -0
  100. data/spec/component_template_spec.rb +40 -0
  101. data/spec/dependency_spec.rb +6 -0
  102. data/spec/dtk_shell_spec.rb +13 -0
  103. data/spec/dtk_spec.rb +33 -0
  104. data/spec/lib/spec_helper.rb +10 -0
  105. data/spec/lib/spec_thor.rb +105 -0
  106. data/spec/module_spec.rb +35 -0
  107. data/spec/node_spec.rb +43 -0
  108. data/spec/node_template_spec.rb +25 -0
  109. data/spec/project_spec.rb +6 -0
  110. data/spec/repo_spec.rb +7 -0
  111. data/spec/response_spec.rb +52 -0
  112. data/spec/service_spec.rb +41 -0
  113. data/spec/state_change_spec.rb +7 -0
  114. data/spec/table_print_spec.rb +48 -0
  115. data/spec/target_spec.rb +57 -0
  116. data/spec/task_spec.rb +28 -0
  117. data/views/assembly/augmented_simple_list.rb +12 -0
  118. data/views/assembly_template/augmented_simple_list.rb +12 -0
  119. data/views/list_task/augmented_simple_list.rb +12 -0
  120. metadata +351 -0
@@ -0,0 +1,1089 @@
1
+ require 'rest_client'
2
+ require 'json'
3
+ require 'colorize'
4
+ dtk_require_from_base("dtk_logger")
5
+ dtk_require_from_base("util/os_util")
6
+ dtk_require_from_base("command_helper")
7
+ dtk_require_common_commands('thor/task_status')
8
+ dtk_require_common_commands('thor/set_required_params')
9
+ dtk_require_common_commands('thor/edit')
10
+ dtk_require_common_commands('thor/purge_clone')
11
+ LOG_SLEEP_TIME_W = DTK::Configuration.get(:tail_log_frequency)
12
+
13
+ module DTK::Client
14
+ module AssemblyWorkspaceMixin
15
+ REQ_ASSEMBLY_OR_WS_ID = [:service_id!, :workspace_id!]
16
+ def get_name(assembly_or_workspace_id)
17
+ get_name_from_id_helper(assembly_or_workspace_id)
18
+ end
19
+
20
+ def start_aux(context_params)
21
+ if context_params.is_there_identifier?(:node)
22
+ mapping = [REQ_ASSEMBLY_OR_WS_ID,:node_id]
23
+ else
24
+ mapping = [REQ_ASSEMBLY_OR_WS_ID,:option_1]
25
+ end
26
+
27
+ assembly_or_workspace_id, node_pattern = context_params.retrieve_arguments(mapping,method_argument_names)
28
+ assembly_start(assembly_or_workspace_id, node_pattern)
29
+ end
30
+
31
+ def stop_aux(context_params)
32
+ if context_params.is_there_identifier?(:node)
33
+ mapping = [REQ_ASSEMBLY_OR_WS_ID,:node_id]
34
+ else
35
+ mapping = [REQ_ASSEMBLY_OR_WS_ID,:option_1]
36
+ end
37
+
38
+ assembly_or_workspace_id, node_pattern = context_params.retrieve_arguments(mapping,method_argument_names)
39
+ assembly_stop(assembly_or_workspace_id, node_pattern)
40
+ end
41
+
42
+ def cancel_task_aux(context_params)
43
+ assembly_or_workspace_id, task_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:option_1],method_argument_names)
44
+ post_body = {
45
+ :assembly_id => assembly_or_workspace_id
46
+ }
47
+ post_body.merge!(:task_id => task_id) if task_id
48
+ post rest_url("assembly/cancel_task"), post_body
49
+ end
50
+
51
+ #mode will be :create or :update
52
+ def promote_assembly_aux(mode,assembly_or_workspace_id,service_module_name=nil,assembly_template_name=nil)
53
+ post_body = {
54
+ :assembly_id => assembly_or_workspace_id,
55
+ :mode => mode.to_s
56
+ }
57
+ post_body.merge!(:service_module_name => service_module_name) if service_module_name
58
+ post_body.merge!(:assembly_template_name => assembly_template_name) if assembly_template_name
59
+ response = post rest_url("assembly/promote_to_template"), post_body
60
+ # when changing context send request for getting latest assembly_templates instead of getting from cache
61
+ # @@invalidate_map << :assembly_template
62
+
63
+ return response unless response.ok?()
64
+ #synchronize_clone will load new assembly template into service clone on workspace (if it exists)
65
+ commit_sha,workspace_branch = response.data(:commit_sha,:workspace_branch)
66
+ service_module_name ||= response.data(:module_name)
67
+ Helper(:git_repo).synchronize_clone(:service_module,service_module_name,commit_sha,:local_branch=>workspace_branch)
68
+ end
69
+
70
+ def list_violations_aux(context_params)
71
+ assembly_or_workspace_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID],method_argument_names)
72
+ response = post rest_url("assembly/find_violations"),:assembly_id => assembly_or_workspace_id
73
+ response.render_table(:violation)
74
+ end
75
+
76
+ def converge_aux(context_params)
77
+ assembly_or_workspace_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID],method_argument_names)
78
+
79
+ post_body = {
80
+ :assembly_id => assembly_or_workspace_id
81
+ }
82
+
83
+ response = post rest_url("assembly/find_violations"), post_body
84
+ return response unless response.ok?
85
+ if response.data and response.data.size > 0
86
+ #TODO: may not directly print here; isntead use a lower level fn
87
+ error_message = "The following violations were found; they must be corrected before workspace can be converged"
88
+ DTK::Client::OsUtil.print(error_message, :red)
89
+ return response.render_table(:violation)
90
+ end
91
+
92
+ post_body.merge!(:commit_msg => options.commit_msg) if options.commit_msg
93
+
94
+ response = post rest_url("assembly/create_task"), post_body
95
+ return response unless response.ok?
96
+
97
+ if response.data
98
+ confirmation_message = response.data["confirmation_message"]
99
+
100
+ if confirmation_message
101
+ return unless Console.confirmation_prompt("Workspace service is stopped, do you want to start it"+'?')
102
+ post_body.merge!(:start_assembly=>true)
103
+ response = post rest_url("assembly/create_task"), post_body
104
+ return response unless response.ok?
105
+ end
106
+ end
107
+
108
+ # execute task
109
+ task_id = response.data(:task_id)
110
+ post rest_url("task/execute"), "task_id" => task_id
111
+ end
112
+
113
+ def edit_module_aux(context_params)
114
+ assembly_or_workspace_id, component_module_name = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:option_1!],method_argument_names)
115
+ post_body = {
116
+ :assembly_id => assembly_or_workspace_id,
117
+ :module_name => component_module_name,
118
+ :module_type => 'component_module'
119
+ }
120
+ response = post rest_url("assembly/prepare_for_edit_module"), post_body
121
+ return response unless response.ok?
122
+
123
+
124
+ assembly_name,component_module_id,version,repo_url,branch,commit_sha = response.data(:assembly_name,:module_id,:version,:repo_url,:workspace_branch,:branch_head_sha)
125
+ edit_opts = {
126
+ :automatically_clone => true,
127
+ :pull_if_needed => true,
128
+ :assembly_module => {
129
+ :assembly_name => assembly_name,
130
+ :version => version
131
+ },
132
+ :workspace_branch_info => {
133
+ :repo_url => repo_url,
134
+ :branch => branch,
135
+ :module_name => component_module_name,
136
+ :commit_sha => commit_sha
137
+ }
138
+ }
139
+ version = nil #TODO: version associated with assembly is passed in edit_opts, which is a little confusing
140
+ edit_aux(:component_module,component_module_id,component_module_name,version,edit_opts)
141
+ end
142
+
143
+ def edit_workflow_aux(context_params)
144
+ assembly_or_workspace_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID],method_argument_names)
145
+ post_body = {
146
+ :assembly_id => assembly_or_workspace_id,
147
+ :module_type => 'service_module',
148
+ :modification_type => 'workflow'
149
+ }
150
+ response = post rest_url("assembly/prepare_for_edit_module"), post_body
151
+ return response unless response.ok?
152
+ assembly_name,service_module_id,service_module_name,version,repo_url,branch,branch_head_sha,edit_file = response.data(:assembly_name,:module_id,:module_name,:version,:repo_url,:workspace_branch,:branch_head_sha,:edit_file)
153
+ edit_opts = {
154
+ :automatically_clone => true,
155
+ :assembly_module => {
156
+ :assembly_name => assembly_name,
157
+ :version => version
158
+ },
159
+ :workspace_branch_info => {
160
+ :repo_url => repo_url,
161
+ :branch => branch,
162
+ :module_name => service_module_name
163
+ },
164
+ :commit_sha => branch_head_sha,
165
+ :pull_if_needed => true,
166
+ :modification_type => :workflow,
167
+ :edit_file => edit_file
168
+ }
169
+ version = nil #TODO: version associated with assembly is passed in edit_opts, which is a little confusing
170
+ edit_aux(:service_module,service_module_id,service_module_name,version,edit_opts)
171
+ end
172
+
173
+ def edit_attributes_aux(context_params)
174
+ assembly_or_workspace_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID],method_argument_names)
175
+
176
+ # if no format is set then we use 'yaml'
177
+ format = options.format || 'yaml'
178
+ context_params.forward_options( { :format => format})
179
+
180
+ response = list_attributes_aux(context_params)
181
+ return response unless response.ok?
182
+
183
+ attributes_list = response.data
184
+ attributes_hash = attributes_editor(attributes_list, format)
185
+
186
+ post_body = {
187
+ :assembly_id => assembly_or_workspace_id,
188
+ :av_pairs_hash => attributes_hash
189
+ }
190
+
191
+ response = post rest_url("assembly/set_attributes"), post_body
192
+ end
193
+
194
+ def push_module_updates_aux(context_params)
195
+ assembly_or_workspace_id, component_module_name = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:option_1!],method_argument_names)
196
+ post_body = {
197
+ :assembly_id => assembly_or_workspace_id,
198
+ :module_name => component_module_name,
199
+ :module_type => 'component_module'
200
+ }
201
+ post_body.merge!(:force => true) if options.force?
202
+ response = post(rest_url("assembly/promote_module_updates"),post_body)
203
+ return response unless response.ok?
204
+ return Response::Ok.new() unless response.data(:any_updates)
205
+ if dsl_parsing_errors = response.data(:dsl_parsing_errors)
206
+ #TODO: not sure if this should be reached
207
+ error_message = "Module '#{component_module_name}' parsing errors found:\n#{dsl_parsing_errors}\nYou can fix errors using 'edit' command from module context and invoke promote-module-updates again.\n"
208
+ OsUtil.print(dsl_parsed_message, :red)
209
+ return Response::Error.new()
210
+ end
211
+ module_name,branch,ff_change = response.data(:module_name,:workspace_branch,:fast_forward_change)
212
+ ff_change ||= true
213
+ opts = {:local_branch => branch}
214
+ opts.merge!(:hard_reset => true) if !ff_change
215
+ response = Helper(:git_repo).pull_changes?(:component_module,module_name,opts)
216
+ return response unless response.ok?()
217
+ Response::Ok.new()
218
+ end
219
+
220
+ def workflow_info_aux(context_params)
221
+ assembly_or_workspace_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID],method_argument_names)
222
+ post_body = {
223
+ :assembly_id => assembly_or_workspace_id,
224
+ :subtype => 'instance'
225
+ }
226
+ post(rest_url("assembly/info_about_task"),post_body)
227
+ end
228
+
229
+ def task_status_aw_aux(context_params)
230
+ assembly_or_workspace_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID],method_argument_names)
231
+ response = task_status_aux(assembly_or_workspace_id,:assembly,options.wait?)
232
+
233
+ # TODO: Hack which is necessery for the specific problem (DTK-725), we don't get proper error message when there is a timeout doing converge
234
+ unless response == true
235
+ return response.merge("data" => [{ "errors" => {"message" => "Task does not exist for workspace."}}]) unless response["data"]
236
+ response["data"].each do |data|
237
+ if data["errors"]
238
+ data["errors"]["message"] = "[TIMEOUT ERROR] Server is taking too long to respond." if data["errors"]["message"] == "error"
239
+ end
240
+ end
241
+ end
242
+
243
+ response
244
+ end
245
+
246
+ def link_attributes_aux(context_params)
247
+ assembly_id, target_attr_term, source_attr_term = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:option_1!,:option_2!],method_argument_names)
248
+ post_body = {
249
+ :assembly_id => assembly_id,
250
+ :target_attribute_term => target_attr_term,
251
+ :source_attribute_term => source_attr_term
252
+ }
253
+ post rest_url("assembly/add_ad_hoc_attribute_links"), post_body
254
+ end
255
+
256
+ def list_nodes_aux(context_params)
257
+ context_params.method_arguments = ["nodes"]
258
+ list_aux(context_params)
259
+ # list_assemblies(context_params)
260
+ end
261
+
262
+ def list_components_aux(context_params)
263
+ context_params.method_arguments = ["components"]
264
+ list_aux(context_params)
265
+ # list_assemblies(context_params)
266
+ end
267
+
268
+ def list_modules_aux(context_params)
269
+ context_params.method_arguments = ["modules"]
270
+ list_aux(context_params)
271
+ # list_assemblies(context_params)
272
+ end
273
+
274
+ def list_attributes_aux(context_params)
275
+ context_params.method_arguments = ["attributes"]
276
+ list_aux(context_params)
277
+ end
278
+
279
+ def list_tasks_aux(context_params)
280
+ context_params.method_arguments = ["tasks"]
281
+ list_aux(context_params)
282
+ end
283
+
284
+ # desc "WORKSPACE-NAME/ID list-assemblies","List assemblies for current workspace."
285
+ # def list_assemblies(context_params)
286
+ # data_type = :assembly
287
+ # post_body = { :subtype => 'instance', :detail_level => 'nodes' }
288
+ # rest_endpoint = "assembly/list"
289
+ # response = post rest_url(rest_endpoint), post_body
290
+
291
+ # response.render_table(data_type)
292
+ # return response
293
+ # end
294
+
295
+ # desc "WORKSPACE-NAME/ID list-assemblies","List assemblies for current workspace."
296
+ # def list_assemblies(context_params)
297
+ # data_type = :assembly
298
+ # post_body = { :subtype => 'instance', :detail_level => 'nodes' }
299
+ # rest_endpoint = "assembly/list"
300
+ # response = post rest_url(rest_endpoint), post_body
301
+
302
+ # response.render_table(data_type)
303
+ # return response
304
+ # end
305
+
306
+ # desc "WORKSPACE-NAME/ID list-assemblies","List assemblies for current workspace."
307
+ # def list_assemblies(context_params)
308
+ # workspace_id, node_id, component_id, attribute_id, about = context_params.retrieve_arguments([:workspace_id,:node_id,:component_id,:attribute_id,:option_1],method_argument_names)
309
+ # detail_to_include = nil
310
+
311
+ # if about
312
+ # case about
313
+ # when "nodes"
314
+ # data_type = :node
315
+ # when "components"
316
+ # data_type = :component
317
+ # detail_to_include = [:component_dependencies]
318
+ # when "attributes"
319
+ # data_type = :attribute
320
+ # detail_to_include = [:attribute_links]
321
+ # when "tasks"
322
+ # data_type = :task
323
+ # else
324
+ # raise_validation_error_method_usage('list')
325
+ # end
326
+ # end
327
+
328
+ # post_body = {
329
+ # :assembly_id => workspace_id,
330
+ # :node_id => node_id,
331
+ # :component_id => component_id,
332
+ # :subtype => 'instance'
333
+ # }
334
+ # post_body.merge!(:detail_to_include => detail_to_include) if detail_to_include
335
+ # rest_endpoint = "assembly/info_about"
336
+
337
+ # if context_params.is_last_command_eql_to?(:attribute)
338
+ # raise DTK::Client::DtkError, "Not supported command for current context level." if attribute_id
339
+ # about, data_type = get_type_and_raise_error_if_invalid(about, "attributes", ["attributes"])
340
+ # elsif context_params.is_last_command_eql_to?(:component)
341
+ # if component_id
342
+ # about, data_type = get_type_and_raise_error_if_invalid(about, "attributes", ["attributes"])
343
+ # else
344
+ # about, data_type = get_type_and_raise_error_if_invalid(about, "components", ["attributes", "components"])
345
+ # end
346
+ # elsif context_params.is_last_command_eql_to?(:node)
347
+ # if node_id
348
+ # about, data_type = get_type_and_raise_error_if_invalid(about, "components", ["attributes", "components"])
349
+ # data_type = :workspace_attribute
350
+ # else
351
+ # about, data_type = get_type_and_raise_error_if_invalid(about, "nodes", ["attributes", "components", "nodes"])
352
+ # end
353
+ # else
354
+ # if workspace_id
355
+ # about, data_type = get_type_and_raise_error_if_invalid(about, "nodes", ["attributes", "components", "nodes", "tasks"])
356
+ # else
357
+ # data_type = :assembly
358
+ # post_body = { :subtype => 'instance', :detail_level => 'nodes' }
359
+ # rest_endpoint = "assembly/list"
360
+ # end
361
+ # end
362
+
363
+ # post_body[:about] = about
364
+ # response = post rest_url(rest_endpoint), post_body
365
+
366
+ # if (data_type.to_s.eql?("workspace_attribute") && response["data"])
367
+ # response["data"].each do |data|
368
+ # unless(data["linked_to_display_form"].to_s.empty?)
369
+ # data_type = :workspace_attribute_w_link
370
+ # break
371
+ # end
372
+ # end
373
+ # end
374
+
375
+ # # set render view to be used
376
+ # response.render_table(data_type)
377
+
378
+ # return response
379
+ # end
380
+
381
+ def link_attribute_aux(context_params)
382
+ assembly_or_workspace_id, target_attr_term, source_attr_term = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:option_1!,:option_2!],method_argument_names)
383
+ post_body = {
384
+ :assembly_id => assembly_or_workspace_id,
385
+ :target_attribute_term => target_attr_term,
386
+ :source_attribute_term => source_attr_term
387
+ }
388
+ post rest_url("assembly/add_ad_hoc_attribute_links"), post_body
389
+ end
390
+
391
+ def list_attribute_mappings_aux(context_params)
392
+ post_body = Helper(:service_link).post_body_with_id_keys(context_params,method_argument_names)
393
+ post rest_url("assembly/list_attribute_mappings"), post_body
394
+ end
395
+
396
+ def create_component_aux(context_params)
397
+ # If method is invoked from 'assembly/node' level retrieve node_id argument
398
+ # directly from active context
399
+ if context_params.is_there_identifier?(:node)
400
+ mapping = [REQ_ASSEMBLY_OR_WS_ID,:node_id!,:option_1!]
401
+ else
402
+ # otherwise retrieve node_id from command options
403
+ mapping = [REQ_ASSEMBLY_OR_WS_ID,:option_1!,:option_2!]
404
+ end
405
+
406
+ assembly_id,node_id,component_template_id = context_params.retrieve_arguments(mapping,method_argument_names)
407
+
408
+ post_body = {
409
+ :assembly_id => assembly_id,
410
+ :node_id => node_id,
411
+ :component_template_id => component_template_id
412
+ }
413
+
414
+ post rest_url("assembly/add_component"), post_body
415
+ end
416
+
417
+ def unlink_components_aux(context_params)
418
+ post_body = link_unlink_components__ret_post_body(context_params)
419
+ post rest_url("assembly/delete_service_link"), post_body
420
+ end
421
+
422
+ def link_components_aux(context_params)
423
+ post_body = link_unlink_components__ret_post_body(context_params)
424
+ post rest_url("assembly/add_service_link"), post_body
425
+ end
426
+
427
+ def link_unlink_components__ret_post_body(context_params)
428
+ if context_params.is_last_command_eql_to?(:component)
429
+ assembly_or_workspace_id,dep_cmp,antec_cmp,dependency_name = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:component_id!,:option_1!,:option_2],method_argument_names)
430
+ else
431
+ assembly_or_workspace_id,dep_cmp,antec_cmp,dependency_name = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:option_1!,:option_2!,:option_3],method_argument_names)
432
+ end
433
+ post_body = {
434
+ :assembly_id => assembly_or_workspace_id,
435
+ :input_component_id => dep_cmp,
436
+ :output_component_id => antec_cmp
437
+ }
438
+ post_body.merge!(:dependency_name => dependency_name) if dependency_name
439
+ post_body
440
+ end
441
+
442
+ def list_component_links_aux(context_params)
443
+ assembly_or_workspace_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID],method_argument_names)
444
+ post_body = {
445
+ :assembly_id => assembly_or_workspace_id
446
+ }
447
+ data_type = :service_link
448
+ if context_params.is_last_command_eql_to?(:component)
449
+ component_id = context_params.retrieve_arguments([:component_id!],method_argument_names)
450
+ post_body.merge!(:component_id => component_id, :context => "component")
451
+ data_type = :service_link_from_component
452
+ end
453
+ response = post rest_url("assembly/list_service_links"), post_body
454
+ response.render_table(data_type)
455
+ end
456
+
457
+ def list_connections_aux(context_params)
458
+ assembly_or_workspace_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID],method_argument_names)
459
+
460
+ post_body = {
461
+ :assembly_id => assembly_or_workspace_id,
462
+ :find_possible => true
463
+ }
464
+ response = post rest_url("assembly/list_connections"), post_body
465
+ response.render_table(:possible_service_connection)
466
+ end
467
+
468
+ def list_smoketests(context_params)
469
+ assembly_or_workspace_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID],method_argument_names)
470
+
471
+ post_body = {
472
+ :assembly_id => assembly_or_workspace_id
473
+ }
474
+ post rest_url("assembly/list_smoketests"), post_body
475
+ end
476
+
477
+ def info_aux(context_params)
478
+ assembly_or_workspace_id, node_id, component_id, attribute_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID, :node_id, :component_id, :attribute_id],method_argument_names)
479
+
480
+ post_body = {
481
+ :assembly_id => assembly_or_workspace_id,
482
+ :node_id => node_id,
483
+ :component_id => component_id,
484
+ :attribute_id => attribute_id,
485
+ :subtype => :instance
486
+ }
487
+
488
+ resp = post rest_url("assembly/info"), post_body
489
+ if (component_id.nil? && !node_id.nil?)
490
+ resp.render_workspace_node_info("node")
491
+ elsif (component_id && node_id)
492
+ resp.render_workspace_node_info("component")
493
+ else
494
+ return resp
495
+ end
496
+ end
497
+
498
+ def delete_and_destroy(context_params)
499
+ assembly_or_workspace_id = context_params.retrieve_arguments([:option_1!],method_argument_names)
500
+ assembly_name = get_name(assembly_or_workspace_id)
501
+
502
+ unless options.force?
503
+ # Ask user if really want to delete assembly, if not then return to dtk-shell without deleting
504
+ #used form "+'?' because ?" confused emacs ruby rendering
505
+ what = "service"
506
+ return unless Console.confirmation_prompt("Are you sure you want to delete and destroy #{what} '#{assembly_name}' and its nodes"+'?')
507
+ end
508
+
509
+ #purge local clone
510
+ response = purge_clone_aux(:all,:assembly_module => {:assembly_name => assembly_name})
511
+ return response unless response.ok?
512
+
513
+ post_body = {
514
+ :assembly_id => assembly_or_workspace_id,
515
+ :subtype => :instance
516
+ }
517
+
518
+ response = post rest_url("assembly/delete"), post_body
519
+
520
+ # when changing context send request for getting latest assemblies instead of getting from cache
521
+ # @@invalidate_map << :assembly
522
+ response
523
+ end
524
+
525
+ def set_target_aux(context_params)
526
+ assembly_or_workspace_id, target_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:option_1!],method_argument_names)
527
+ post_body = {
528
+ :assembly_id => assembly_or_workspace_id,
529
+ :target_id => target_id
530
+ }
531
+ post rest_url("assembly/set_target"), post_body
532
+ end
533
+
534
+ def set_attribute_aux(context_params)
535
+ if context_params.is_there_identifier?(:attribute)
536
+ mapping = (options.unset? ? [REQ_ASSEMBLY_OR_WS_ID,:attribute_id!] : [REQ_ASSEMBLY_OR_WS_ID,:attribute_id!,:option_1!])
537
+ else
538
+ mapping = (options.unset? ? [REQ_ASSEMBLY_OR_WS_ID,:option_1!] : [REQ_ASSEMBLY_OR_WS_ID,:option_1!,:option_2!])
539
+ end
540
+
541
+ assembly_or_workspace_id, pattern, value = context_params.retrieve_arguments(mapping,method_argument_names)
542
+ post_body = {
543
+ :assembly_id => assembly_or_workspace_id,
544
+ :pattern => pattern
545
+ }
546
+ post_body.merge!(:value => value) unless options.unset?
547
+ post rest_url("assembly/set_attributes"), post_body
548
+ end
549
+
550
+ def create_attribute_aux(context_params)
551
+ if context_params.is_there_identifier?(:attribute)
552
+ mapping = [REQ_ASSEMBLY_OR_WS_ID,:attribute_id!, :option_1]
553
+ else
554
+ mapping = [REQ_ASSEMBLY_OR_WS_ID,:option_1!,:option_2]
555
+ end
556
+ assembly_id, pattern, value = context_params.retrieve_arguments(mapping,method_argument_names)
557
+ post_body = {
558
+ :assembly_id => assembly_id,
559
+ :pattern => pattern,
560
+ :create => true,
561
+ }
562
+ post_body.merge!(:value => value) if value
563
+ post_body.merge!(:required => true) if options.required?
564
+ post_body.merge!(:dynamic => true) if options.dynamic?
565
+ if datatype = options.type
566
+ post_body.merge!(:datatype => datatype)
567
+ end
568
+ post rest_url("assembly/set_attributes"), post_body
569
+ end
570
+
571
+ def unset(context_params)
572
+ if context_params.is_there_identifier?(:attribute)
573
+ mapping = [[:service_id, :workspace_id!],:attribute_id!]
574
+ else
575
+ mapping = [[:service_id, :workspace_id!],:option_1!]
576
+ end
577
+
578
+ assembly_or_workspace_id, pattern, value = context_params.retrieve_arguments(mapping,method_argument_names)
579
+
580
+ post_body = {
581
+ :assembly_id => assembly_or_workspace_id,
582
+ :pattern => pattern,
583
+ :value => nil
584
+ }
585
+ #TODO: have this return format like assembly show attributes with subset of rows that gt changed
586
+ post rest_url("assembly/set_attributes"), post_body
587
+ end
588
+
589
+ def add_assembly(context_params)
590
+ assembly_or_workspace_id,assembly_template_id = context_params.retrieve_arguments([[:service_id, :workspace_id!],:option_1!],method_argument_names)
591
+ post_body = {
592
+ :assembly_id => assembly_or_workspace_id,
593
+ :assembly_template_id => assembly_template_id
594
+ }
595
+ post_body.merge!(:auto_add_connections => true) if options.auto_complete?
596
+ post rest_url("assembly/add_assembly_template"), post_body
597
+ end
598
+
599
+ def create_node_aux(context_params)
600
+ assembly_or_workspace_id,assembly_node_name,node_template_identifier = context_params.retrieve_arguments([[:service_id, :workspace_id!],:option_1!,:option_2!],method_argument_names)
601
+ post_body = {
602
+ :assembly_id => assembly_or_workspace_id,
603
+ :assembly_node_name => assembly_node_name
604
+ }
605
+ post_body.merge!(:node_template_identifier => node_template_identifier) if node_template_identifier
606
+ post rest_url("assembly/add_node"), post_body
607
+ end
608
+
609
+ def purge_aux(context_params)
610
+ assembly_or_workspace_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID],method_argument_names)
611
+ unless options.force?
612
+ return unless Console.confirmation_prompt("Are you sure you want to delete and destroy all nodes in the workspace"+'?')
613
+ end
614
+
615
+ post_body = {
616
+ :assembly_id => assembly_or_workspace_id
617
+ }
618
+ response = post(rest_url("assembly/purge"),post_body)
619
+ end
620
+
621
+ def delete_aux(context_params)
622
+ if context_params.is_last_command_eql_to?(:node)
623
+ delete_node_aux(context_params)
624
+ elsif context_params.is_last_command_eql_to?(:component)
625
+ delete_component_aux(context_params)
626
+ end
627
+ end
628
+
629
+ def delete_node_aux(context_params)
630
+ assembly_or_workspace_id, node_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:option_1!],method_argument_names)
631
+ unless options.force?
632
+ what = "node"
633
+ return unless Console.confirmation_prompt("Are you sure you want to delete and destroy #{what} '#{node_id}'"+'?')
634
+ end
635
+
636
+ post_body = {
637
+ :assembly_id => assembly_or_workspace_id,
638
+ :node_id => node_id
639
+ }
640
+ response = post(rest_url("assembly/delete_node"),post_body)
641
+ # @@invalidate_map << :assembly_node
642
+ response
643
+ end
644
+
645
+ def delete_component_aux(context_params)
646
+ assembly_or_workspace_id, node_id, node_name, component_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:node_id, :node_name, :option_1!],method_argument_names)
647
+
648
+ unless options.force?
649
+ what = "component"
650
+ return unless Console.confirmation_prompt("Are you sure you want to delete #{what} '#{component_id}'"+'?')
651
+ end
652
+
653
+ post_body = {
654
+ :assembly_id => assembly_or_workspace_id,
655
+ :node_id => node_id,
656
+ :component_id => component_id
657
+ }
658
+
659
+ # delete component by name (e.g. delete-component dtk_java)
660
+ post_body.merge!(:cmp_full_name => "#{node_name}/#{component_id}") if (node_name && !(component_id.to_s =~ /^[0-9]+$/))
661
+ response = post(rest_url("assembly/delete_component"),post_body)
662
+ end
663
+
664
+ def get_netstats_aux(context_params)
665
+ netstat_tries = 6
666
+ netstat_sleep = 0.5
667
+
668
+ assembly_or_workspace_id,node_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:node_id],method_argument_names)
669
+
670
+ post_body = {
671
+ :assembly_id => assembly_or_workspace_id,
672
+ :node_id => node_id
673
+ }
674
+
675
+ response = post(rest_url("assembly/initiate_get_netstats"),post_body)
676
+ return response unless response.ok?
677
+
678
+ action_results_id = response.data(:action_results_id)
679
+ end_loop, response, count, ret_only_if_complete = false, nil, 0, true
680
+
681
+ until end_loop do
682
+ post_body = {
683
+ :action_results_id => action_results_id,
684
+ :return_only_if_complete => ret_only_if_complete,
685
+ :disable_post_processing => false,
686
+ :sort_key => "port"
687
+ }
688
+ response = post(rest_url("assembly/get_action_results"),post_body)
689
+ count += 1
690
+ if count > netstat_tries or response.data(:is_complete)
691
+ end_loop = true
692
+ else
693
+ #last time in loop return whetever is teher
694
+ if count == netstat_tries
695
+ ret_only_if_complete = false
696
+ end
697
+ sleep netstat_sleep
698
+ end
699
+ end
700
+
701
+ #TODO: needed better way to render what is one of the fields which is any array (:results in this case)
702
+ response.set_data(*response.data(:results))
703
+ response.render_table(:netstat_data)
704
+ end
705
+
706
+ def get_ps_aux(context_params)
707
+ get_ps_tries = 6
708
+ get_ps_sleep = 0.5
709
+
710
+ assembly_or_workspace_id,node_id,filter_pattern = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID,:node_id, :option_1],method_argument_names)
711
+
712
+ post_body = {
713
+ :assembly_id => assembly_or_workspace_id,
714
+ :node_id => node_id
715
+ }
716
+
717
+ response = post(rest_url("assembly/initiate_get_ps"),post_body)
718
+ return response unless response.ok?
719
+
720
+ action_results_id = response.data(:action_results_id)
721
+ end_loop, response, count, ret_only_if_complete = false, nil, 0, true
722
+
723
+ until end_loop do
724
+ post_body = {
725
+ :action_results_id => action_results_id,
726
+ :return_only_if_complete => ret_only_if_complete,
727
+ :disable_post_processing => false,
728
+ :sort_key => "pid"
729
+ }
730
+ response = post(rest_url("assembly/get_action_results"),post_body)
731
+ count += 1
732
+ if count > get_ps_tries or response.data(:is_complete)
733
+ end_loop = true
734
+ else
735
+ #last time in loop return whetever is teher
736
+ if count == get_ps_tries
737
+ ret_only_if_complete = false
738
+ end
739
+ sleep get_ps_sleep
740
+ end
741
+ end
742
+ filtered = response.data(:results).flatten
743
+
744
+ # Amar: had to add more complex filtering in order to print node id and node name in output,
745
+ # as these two values are sent only in the first element of node's processes list
746
+ unless (filter_pattern.nil? || !options["filter"])
747
+ node_id = ""
748
+ node_name = ""
749
+ filtered.reject! do |r|
750
+ match = r.to_s.include?(filter_pattern)
751
+ if r["node_id"] && r["node_id"] != node_id
752
+ node_id = r["node_id"]
753
+ node_name = r["node_name"]
754
+ end
755
+
756
+ if match && !node_id.empty?
757
+ r["node_id"] = node_id
758
+ r["node_name"] = node_name
759
+ node_id = ""
760
+ node_name = ""
761
+ end
762
+ !match
763
+ end
764
+ end
765
+
766
+ response.set_data(*filtered)
767
+ response.render_table(:ps_data)
768
+ end
769
+
770
+ def set_required_params(context_params)
771
+ assembly_or_workspace_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID],method_argument_names)
772
+ set_required_params_aux(assembly_or_workspace_id,:assembly,:instance)
773
+ end
774
+
775
+ def tail_aux(context_params)
776
+ if context_params.is_there_identifier?(:node)
777
+ mapping = [REQ_ASSEMBLY_OR_WS_ID,:node_id!,:option_1!,:option_2]
778
+ else
779
+ mapping = [REQ_ASSEMBLY_OR_WS_ID,:option_1!,:option_2!,:option_3]
780
+ end
781
+
782
+ assembly_or_workspace_id,node_identifier,log_path,grep_option = context_params.retrieve_arguments(mapping,method_argument_names)
783
+
784
+ last_line = nil
785
+ begin
786
+
787
+ file_path = File.join('/tmp',"dtk_tail_#{Time.now.to_i}.tmp")
788
+ tail_temp_file = File.open(file_path,"a")
789
+
790
+ file_ready = false
791
+
792
+ t1 = Thread.new do
793
+ while true
794
+ post_body = {
795
+ :assembly_id => assembly_or_workspace_id,
796
+ :subtype => 'instance',
797
+ :start_line => last_line,
798
+ :node_identifier => node_identifier,
799
+ :log_path => log_path,
800
+ :grep_option => grep_option
801
+ }
802
+
803
+ response = post rest_url("assembly/initiate_get_log"), post_body
804
+
805
+ unless response.ok?
806
+ raise DTK::Client::DtkError, "Error while getting log from server, there was no successful response."
807
+ end
808
+
809
+ action_results_id = response.data(:action_results_id)
810
+ action_body = {
811
+ :action_results_id => action_results_id,
812
+ :return_only_if_complete => true,
813
+ :disable_post_processing => true
814
+ }
815
+
816
+ # number of re-tries
817
+ 3.times do
818
+ response = post(rest_url("assembly/get_action_results"),action_body)
819
+
820
+ # server has found an error
821
+ unless response.data(:results).nil?
822
+ if response.data(:results)['error']
823
+ raise DTK::Client::DtkError, response.data(:results)['error']
824
+ end
825
+ end
826
+
827
+ break if response.data(:is_complete)
828
+
829
+ sleep(1)
830
+ end
831
+
832
+ raise DTK::Client::DtkError, "Error while logging there was no successful response after 3 tries." unless response.data(:is_complete)
833
+
834
+ # due to complicated response we change its formating
835
+ response = response.data(:results).first[1]
836
+
837
+ unless response["error"].nil?
838
+ raise DTK::Client::DtkError, response["error"]
839
+ end
840
+
841
+ # removing invalid chars from log
842
+ output = response["output"].gsub(/`/,'\'')
843
+
844
+ unless output.empty?
845
+ file_ready = true
846
+ tail_temp_file << output
847
+ tail_temp_file.flush
848
+ end
849
+
850
+ last_line = response["last_line"]
851
+ sleep(LOG_SLEEP_TIME_W)
852
+ end
853
+ end
854
+
855
+ t2 = Thread.new do
856
+ # ramp up time
857
+ begin
858
+ if options.more?
859
+ system("tail -f #{file_path} | more")
860
+ else
861
+ # needed ramp up time for t1 to start writting to file
862
+ while not file_ready
863
+ sleep(0.5)
864
+ end
865
+ system("less +F #{file_path}")
866
+ end
867
+ ensure
868
+ # wheter application resolves normaly or is interrupted
869
+ # t1 will be killed
870
+ t1.exit()
871
+ end
872
+ end
873
+
874
+ t1.join()
875
+ t2.join()
876
+ rescue Interrupt
877
+ t2.exit()
878
+ rescue DTK::Client::DtkError => e
879
+ t2.exit()
880
+ raise e
881
+ end
882
+ end
883
+
884
+ def grep_aux(context_params)
885
+ if context_params.is_there_identifier?(:node)
886
+ mapping = [REQ_ASSEMBLY_OR_WS_ID,:option_1!,:node_id!,:option_2!]
887
+ else
888
+ mapping = [REQ_ASSEMBLY_OR_WS_ID,:option_1!,:option_2!,:option_3!]
889
+ end
890
+
891
+ assembly_or_workspace_id,log_path,node_pattern,grep_pattern = context_params.retrieve_arguments(mapping,method_argument_names)
892
+
893
+ begin
894
+ post_body = {
895
+ :assembly_id => assembly_or_workspace_id,
896
+ :subtype => 'instance',
897
+ :log_path => log_path,
898
+ :node_pattern => node_pattern,
899
+ :grep_pattern => grep_pattern,
900
+ :stop_on_first_match => options.first?
901
+ }
902
+
903
+ response = post rest_url("assembly/initiate_grep"), post_body
904
+
905
+ unless response.ok?
906
+ raise DTK::Client::DtkError, "Error while getting log from server. Message: #{response['errors'][0]['message'].nil? ? 'There was no successful response.' : response['errors'].first['message']}"
907
+ end
908
+
909
+ action_results_id = response.data(:action_results_id)
910
+ action_body = {
911
+ :action_results_id => action_results_id,
912
+ :return_only_if_complete => true,
913
+ :disable_post_processing => true
914
+ }
915
+
916
+ # number of re-tries
917
+ 3.downto(1) do
918
+ response = post(rest_url("assembly/get_action_results"),action_body)
919
+
920
+ # server has found an error
921
+ unless response.data(:results).nil?
922
+ if response.data(:results)['error']
923
+ raise DTK::Client::DtkError, response.data(:results)['error']
924
+ end
925
+ end
926
+
927
+ break if response.data(:is_complete)
928
+
929
+ sleep(1)
930
+ end
931
+
932
+ raise DTK::Client::DtkError, "Error while logging there was no successful response after 3 tries." unless response.data(:is_complete)
933
+
934
+ console_width = ENV["COLUMNS"].to_i
935
+
936
+ response.data(:results).each do |r|
937
+ raise DTK::Client::DtkError, r[1]["error"] if r[1]["error"]
938
+
939
+ message_colorized = DTK::Client::OsUtil.colorize(r[0].inspect, :green)
940
+
941
+ if r[1]["output"].empty?
942
+ puts "NODE-ID #{message_colorized} - Log does not contain data that matches you pattern #{grep_pattern}!"
943
+ else
944
+ puts "\n"
945
+ console_width.times do
946
+ print "="
947
+ end
948
+ puts "NODE-ID: #{message_colorized}\n"
949
+ puts "Log output:\n"
950
+ puts r[1]["output"].gsub(/`/,'\'')
951
+ end
952
+ end
953
+ rescue DTK::Client::DtkError => e
954
+ raise e
955
+ end
956
+ end
957
+
958
+ def assembly_start(workspace_id, node_pattern_filter)
959
+ post_body = {
960
+ :assembly_id => workspace_id,
961
+ :node_pattern => node_pattern_filter
962
+ }
963
+
964
+ # we expect action result ID
965
+ response = post rest_url("assembly/start"), post_body
966
+ raise DTK::Client::DtkValidationError, response.data(:errors).first if response.data(:errors)
967
+
968
+ task_id = response.data(:task_id)
969
+ post rest_url("task/execute"), "task_id" => task_id
970
+ end
971
+
972
+ def assembly_stop(workspace_id, node_pattern_filter)
973
+ post_body = {
974
+ :assembly_id => workspace_id,
975
+ :node_pattern => node_pattern_filter
976
+ }
977
+
978
+ response = post rest_url("assembly/stop"), post_body
979
+ raise DTK::Client::DtkValidationError, response.data(:errors).first if response.data(:errors)
980
+
981
+ return response
982
+ end
983
+
984
+ def list_aux(context_params)
985
+ assembly_or_workspace_id, node_id, component_id, attribute_id, about = context_params.retrieve_arguments([[:service_id!, :workspace_id],:node_id,:component_id,:attribute_id,:option_1],method_argument_names)
986
+ detail_to_include = nil
987
+ format = nil
988
+ post_options = Hash.new
989
+
990
+ # use_default is used if we want to use provided data_type and not data_type returned from server
991
+ use_default = false
992
+
993
+ # if list method is called outside of dtk-shell and called for workspace context (dtk workspace list-nodes)
994
+ # without workspace identifier, we will set 'workspace' as identifier (dtk workspace workspace list-nodes)
995
+ assembly_or_workspace_id = 'workspace' if (context_params.is_last_command_eql_to?(:workspace) && assembly_or_workspace_id.nil?)
996
+
997
+ #TODO: looking for cleaner way of showing which ones are using the default datatype passed back from server;
998
+ #might use data_type = DynamicDatatype
999
+ if about
1000
+ case about
1001
+ when "nodes"
1002
+ data_type = :node
1003
+ when "components"
1004
+ data_type = :component
1005
+ if options.deps?
1006
+ detail_to_include = [:component_dependencies]
1007
+ end
1008
+ when "attributes"
1009
+ data_type = (options.links? ? :workspace_attribute_w_link : :workspace_attribute)
1010
+ edit_attr_format = context_params.get_forwarded_options()[:format] if context_params.get_forwarded_options()
1011
+ if format = (options.format || edit_attr_format)
1012
+ post_options.merge!(:format => format)
1013
+ #dont need to compute links if using a format
1014
+ elsif options.links?
1015
+ detail_to_include = [:attribute_links]
1016
+ end
1017
+ when "modules"
1018
+ detail_to_include = [:version_info]
1019
+ data_type = nil #TODO: DynamicDatatype
1020
+ when "tasks"
1021
+ data_type = :task
1022
+ else
1023
+ raise_validation_error_method_usage('list')
1024
+ end
1025
+ end
1026
+
1027
+ post_body = {
1028
+ :assembly_id => assembly_or_workspace_id,
1029
+ :node_id => node_id,
1030
+ :component_id => component_id,
1031
+ :subtype => 'instance',
1032
+ }.merge(post_options)
1033
+
1034
+ post_body.merge!(:detail_to_include => detail_to_include) if detail_to_include
1035
+ rest_endpoint = "assembly/info_about"
1036
+
1037
+ if context_params.is_last_command_eql_to?(:attribute)
1038
+ raise DTK::Client::DtkError, "Not supported command for current context level." if attribute_id
1039
+ about, data_type = get_type_and_raise_error_if_invalid(about, "attributes", ["attributes"])
1040
+ elsif context_params.is_last_command_eql_to?(:component)
1041
+ if component_id
1042
+ about, data_type = get_type_and_raise_error_if_invalid(about, "attributes", ["attributes"])
1043
+ else
1044
+ about, data_type = get_type_and_raise_error_if_invalid(about, "components", ["attributes", "components"])
1045
+ end
1046
+ elsif context_params.is_last_command_eql_to?(:node)
1047
+ if node_id
1048
+ about, data_type = get_type_and_raise_error_if_invalid(about, "components", ["attributes", "components"])
1049
+ else
1050
+ about, data_type = get_type_and_raise_error_if_invalid(about, "nodes", ["attributes", "components", "nodes"])
1051
+ end
1052
+ else
1053
+ if assembly_or_workspace_id
1054
+ about, data_type = get_type_and_raise_error_if_invalid(about, "nodes", ["attributes", "components", "nodes", "modules","tasks"])
1055
+
1056
+ if data_type.to_s.eql?("component")
1057
+ data_type = nil #DynamicDatatype
1058
+ end
1059
+ #TODO: need to cleanup that data_type set in multiple places
1060
+ if about == "attributes"
1061
+ data_type = (options.links? ? :workspace_attribute_w_link : :workspace_attribute)
1062
+ end
1063
+ else
1064
+ data_type = :assembly
1065
+ post_body = { :subtype => 'instance', :detail_level => 'nodes' }
1066
+ rest_endpoint = "assembly/list"
1067
+ end
1068
+ end
1069
+
1070
+ post_body[:about] = about
1071
+ response = post rest_url(rest_endpoint), post_body
1072
+ # set render view to be used
1073
+ unless format
1074
+ response.render_table(data_type, use_default)
1075
+ end
1076
+
1077
+ response
1078
+ end
1079
+
1080
+ def clear_tasks_aux(context_params)
1081
+ assembly_or_workspace_id = context_params.retrieve_arguments([REQ_ASSEMBLY_OR_WS_ID],method_argument_names)
1082
+ post_body = {
1083
+ :assembly_id => assembly_or_workspace_id
1084
+ }
1085
+ post rest_url("assembly/clear_tasks"), post_body
1086
+ end
1087
+
1088
+ end
1089
+ end