aspera-cli 4.26.1 → 4.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +300 -22
  4. data/CONTRIBUTING.md +100 -12
  5. data/bin/ascli +5 -5
  6. data/docs/README.md +10757 -0
  7. data/docs/test-mcp-with-ai.md +202 -0
  8. data/lib/aspera/agent/base.rb +20 -6
  9. data/lib/aspera/agent/connect.rb +53 -16
  10. data/lib/aspera/agent/desktop.rb +52 -17
  11. data/lib/aspera/agent/direct.rb +27 -25
  12. data/lib/aspera/agent/factory.rb +4 -0
  13. data/lib/aspera/agent/httpgw.rb +2 -2
  14. data/lib/aspera/agent/node.rb +34 -2
  15. data/lib/aspera/agent/transferd.rb +39 -3
  16. data/lib/aspera/api/alee.rb +1 -1
  17. data/lib/aspera/api/aoc.rb +56 -51
  18. data/lib/aspera/api/cos_node.rb +2 -2
  19. data/lib/aspera/api/faspex.rb +22 -20
  20. data/lib/aspera/api/httpgw.rb +4 -4
  21. data/lib/aspera/api/node.rb +33 -30
  22. data/lib/aspera/api/queries/bss_subscription_account.graphql +18 -0
  23. data/lib/aspera/api/queries/bss_subscription_usage.graphql +18 -0
  24. data/lib/aspera/ascmd.rb +25 -23
  25. data/lib/aspera/ascp/installation.rb +43 -40
  26. data/lib/aspera/ascp/management.rb +2 -3
  27. data/lib/aspera/cli/ascp_actions.rb +155 -0
  28. data/lib/aspera/cli/async_transfer_store.rb +81 -0
  29. data/lib/aspera/cli/bootstrapper.rb +197 -0
  30. data/lib/aspera/cli/command_registry.rb +145 -0
  31. data/lib/aspera/cli/command_spec.rb +138 -0
  32. data/lib/aspera/cli/context.rb +71 -0
  33. data/lib/aspera/cli/error.rb +16 -0
  34. data/lib/aspera/cli/extended_value.rb +5 -3
  35. data/lib/aspera/cli/formatter.rb +122 -209
  36. data/lib/aspera/cli/gem_checker.rb +65 -0
  37. data/lib/aspera/cli/hints.rb +2 -2
  38. data/lib/aspera/cli/http.rb +218 -0
  39. data/lib/aspera/cli/info.rb +2 -0
  40. data/lib/aspera/cli/mailer.rb +97 -0
  41. data/lib/aspera/cli/mcp_tool.rb +198 -0
  42. data/lib/aspera/cli/options.schema.yaml +364 -7
  43. data/lib/aspera/cli/{manager.rb → parser.rb} +337 -144
  44. data/lib/aspera/cli/plugins/alee.rb +20 -22
  45. data/lib/aspera/cli/plugins/aoc.rb +1173 -849
  46. data/lib/aspera/cli/plugins/ats.rb +200 -161
  47. data/lib/aspera/cli/plugins/base.rb +470 -107
  48. data/lib/aspera/cli/plugins/basic_auth.rb +14 -4
  49. data/lib/aspera/cli/plugins/config.rb +434 -1032
  50. data/lib/aspera/cli/plugins/console.rb +106 -64
  51. data/lib/aspera/cli/plugins/cos.rb +44 -32
  52. data/lib/aspera/cli/plugins/factory.rb +7 -4
  53. data/lib/aspera/cli/plugins/faspex.rb +296 -259
  54. data/lib/aspera/cli/plugins/faspex5.rb +592 -344
  55. data/lib/aspera/cli/plugins/faspio.rb +49 -51
  56. data/lib/aspera/cli/plugins/httpgw.rb +18 -25
  57. data/lib/aspera/cli/plugins/mcp.rb +279 -0
  58. data/lib/aspera/cli/plugins/node.rb +1001 -797
  59. data/lib/aspera/cli/plugins/oauth.rb +7 -10
  60. data/lib/aspera/cli/plugins/orchestrator.rb +111 -139
  61. data/lib/aspera/cli/plugins/preview.rb +183 -142
  62. data/lib/aspera/cli/plugins/server.rb +125 -80
  63. data/lib/aspera/cli/plugins/shares.rb +301 -107
  64. data/lib/aspera/cli/preset_actions.rb +139 -0
  65. data/lib/aspera/cli/preset_manager.rb +236 -0
  66. data/lib/aspera/cli/result.rb +360 -0
  67. data/lib/aspera/cli/runner.rb +473 -0
  68. data/lib/aspera/cli/secret_finder.rb +40 -0
  69. data/lib/aspera/cli/special_values.rb +1 -0
  70. data/lib/aspera/cli/sync_actions.rb +84 -56
  71. data/lib/aspera/cli/terminal_formatter.rb +65 -0
  72. data/lib/aspera/cli/transfer_actions.rb +83 -0
  73. data/lib/aspera/cli/transfer_agent.rb +116 -51
  74. data/lib/aspera/cli/transfer_progress.rb +9 -9
  75. data/lib/aspera/cli/vault_manager.rb +57 -0
  76. data/lib/aspera/cli/version.rb +1 -1
  77. data/lib/aspera/cli/wizard.rb +26 -26
  78. data/lib/aspera/command_line_builder.rb +23 -23
  79. data/lib/aspera/data_repository.rb +6 -1
  80. data/lib/aspera/dot_container.rb +5 -5
  81. data/lib/aspera/environment.rb +39 -13
  82. data/lib/aspera/exec_spec.rb +13 -0
  83. data/lib/aspera/faspex_gw.rb +2 -2
  84. data/lib/aspera/faspex_postproc.rb +4 -3
  85. data/lib/aspera/graphql.rb +35 -0
  86. data/lib/aspera/hash_ext.rb +6 -0
  87. data/lib/aspera/json_rpc/client.rb +62 -0
  88. data/lib/aspera/json_rpc/version.rb +7 -0
  89. data/lib/aspera/keychain/base.rb +1 -1
  90. data/lib/aspera/keychain/encrypted_hash.rb +2 -2
  91. data/lib/aspera/keychain/factory.rb +4 -4
  92. data/lib/aspera/keychain/macos_security.rb +4 -4
  93. data/lib/aspera/link_header.rb +82 -0
  94. data/lib/aspera/log.rb +23 -5
  95. data/lib/aspera/markdown.rb +85 -2
  96. data/lib/aspera/nagios.rb +2 -2
  97. data/lib/aspera/node_simulator.rb +3 -1
  98. data/lib/aspera/oauth/base.rb +10 -10
  99. data/lib/aspera/oauth/boot.rb +43 -0
  100. data/lib/aspera/oauth/factory.rb +41 -15
  101. data/lib/aspera/oauth/jwt.rb +4 -4
  102. data/lib/aspera/oauth/web.rb +4 -4
  103. data/lib/aspera/oauth.rb +1 -0
  104. data/lib/aspera/persistency_action_once.rb +10 -10
  105. data/lib/aspera/persistency_folder.rb +10 -3
  106. data/lib/aspera/preview/file_types.rb +7 -3
  107. data/lib/aspera/preview/generator.rb +3 -3
  108. data/lib/aspera/preview/utils.rb +1 -1
  109. data/lib/aspera/products/connect.rb +4 -1
  110. data/lib/aspera/products/other.rb +1 -1
  111. data/lib/aspera/products/transferd.rb +3 -3
  112. data/lib/aspera/proxy_auto_config.rb +10 -9
  113. data/lib/aspera/rest.rb +18 -40
  114. data/lib/aspera/rest_error_analyzer.rb +7 -3
  115. data/lib/aspera/rest_errors_aspera.rb +0 -10
  116. data/lib/aspera/rest_list.rb +13 -6
  117. data/lib/aspera/schema/IBM Aspera Faspex API-5.0-enhanced.yaml +14 -4
  118. data/lib/aspera/schema/IBM Aspera on Cloud API-0.2.6-enhanced.yaml +2730 -648
  119. data/lib/aspera/schema/async_tables.yaml +361 -0
  120. data/lib/aspera/schema/documentation.rb +57 -26
  121. data/lib/aspera/schema/reader.rb +60 -11
  122. data/lib/aspera/schema/registry.rb +50 -10
  123. data/lib/aspera/secret_hider.rb +11 -2
  124. data/lib/aspera/ssl.rb +4 -4
  125. data/lib/aspera/sync/conf.schema.yaml +2 -2
  126. data/lib/aspera/sync/database.rb +14 -10
  127. data/lib/aspera/sync/operations.rb +15 -18
  128. data/lib/aspera/temp_file_manager.rb +5 -1
  129. data/lib/aspera/timer_limiter.rb +1 -1
  130. data/lib/aspera/transfer/faux_file.rb +24 -11
  131. data/lib/aspera/transfer/parameters.rb +27 -25
  132. data/lib/aspera/transfer/result.rb +74 -0
  133. data/lib/aspera/transfer/resumer.rb +7 -7
  134. data/lib/aspera/transfer/spec.rb +18 -1
  135. data/lib/aspera/transfer/spec.schema.yaml +26 -8
  136. data/lib/aspera/transfer/uri.rb +1 -1
  137. data/lib/aspera/uri_reader.rb +2 -2
  138. data/lib/aspera/web_auth.rb +2 -2
  139. data/lib/aspera/web_server_simple.rb +8 -5
  140. data/lib/aspera/yaml.rb +2 -1
  141. data.tar.gz.sig +0 -0
  142. metadata +45 -16
  143. metadata.gz.sig +0 -0
  144. data/lib/aspera/cli/main.rb +0 -480
  145. data/lib/aspera/json_rpc.rb +0 -51
@@ -9,7 +9,7 @@ module Aspera
9
9
  class Oauth < BasicAuth
10
10
  class << self
11
11
  # Get command line `options` specified by `AUTH_OPTIONS`
12
- # @param options [Cli::Manager] Object to get command line options.
12
+ # @param options [Cli::Parser] Object to get command line options.
13
13
  # @return [Hash{Symbol => Object}] Options
14
14
  # @raise [Cli::Error] if a required option is missing
15
15
  def kwargs_from_options(options)
@@ -28,15 +28,12 @@ module Aspera
28
28
  AUTH_TYPES = %i[web jwt boot].freeze
29
29
  # Options used for authentication (url, auth, client_id, etc...)
30
30
  AUTH_OPTIONS = %i[url auth client_id client_secret redirect_uri private_key passphrase username password].freeze
31
- def initialize(**_)
32
- super
33
- options.declare(:auth, 'OAuth type of authentication', allowed: AUTH_TYPES, default: :jwt)
34
- options.declare(:client_id, 'OAuth client identifier')
35
- options.declare(:client_secret, 'OAuth client secret')
36
- options.declare(:redirect_uri, 'OAuth (Web) redirect URI for web authentication')
37
- options.declare(:private_key, 'OAuth (JWT) RSA private key PEM value (prefix file path with @file:)')
38
- options.declare(:passphrase, 'OAuth (JWT) RSA private key passphrase')
39
- end
31
+ option :auth, description: 'OAuth type of authentication', allowed: AUTH_TYPES, default: :jwt
32
+ option :client_id, description: 'OAuth client identifier'
33
+ option :client_secret, description: 'OAuth client secret'
34
+ option :redirect_uri, description: 'OAuth (Web) redirect URI for web authentication'
35
+ option :private_key, description: 'OAuth (JWT) RSA private key PEM value (prefix file path with @file:)'
36
+ option :passphrase, description: 'OAuth (JWT) RSA private key passphrase'
40
37
  end
41
38
  end
42
39
  end
@@ -15,6 +15,7 @@ module Aspera
15
15
  STANDARD_PATH = '/aspera/orchestrator'
16
16
  TEST_ENDPOINT = 'api/remote_node_ping'
17
17
  private_constant :STANDARD_PATH, :TEST_ENDPOINT
18
+
18
19
  class << self
19
20
  # @return [Hash,NilClass]
20
21
  def detect(address_or_url)
@@ -23,7 +24,7 @@ module Aspera
23
24
  urls.push("#{address_or_url}#{STANDARD_PATH}") unless address_or_url.end_with?(STANDARD_PATH)
24
25
  error = nil
25
26
  urls.each do |base_url|
26
- next unless base_url.match?('https?://')
27
+ next unless base_url.match?(%r{^https?://})
27
28
  api = Rest.new(base_url: base_url)
28
29
  data, http = api.read(TEST_ENDPOINT, query: {format: :json}, ret: :both)
29
30
  next unless data['remote_orchestrator_info']
@@ -55,13 +56,14 @@ module Aspera
55
56
  }
56
57
  end
57
58
 
59
+ option :result, description: "Specify result value as: 'work_step:parameter'"
60
+ option :synchronous, description: 'Wait for completion', allowed: Allowed::TYPES_BOOLEAN, default: false
61
+ option :ret_style, description: 'How return type is requested in api', allowed: %i[header arg ext], default: :arg
62
+ option :auth_style, description: 'Authentication type', allowed: %i[arg_pass head_basic apikey], default: :head_basic
63
+
58
64
  def initialize(**_)
59
65
  super
60
66
  @api_orch = nil
61
- options.declare(:result, "Specify result value as: 'work_step:parameter'")
62
- options.declare(:synchronous, 'Wait for completion', allowed: Allowed::TYPES_BOOLEAN, default: false)
63
- options.declare(:ret_style, 'How return type is requested in api', allowed: %i[header arg ext], default: :arg)
64
- options.declare(:auth_style, 'Authentication type', allowed: %i[arg_pass head_basic apikey], default: :head_basic)
65
67
  options.parse_options!
66
68
  end
67
69
 
@@ -97,9 +99,77 @@ module Aspera
97
99
  return result
98
100
  end
99
101
 
100
- ACTIONS = %i[health info workflows workorders workstep plugins processes monitors].freeze
102
+ private :call_ao
103
+
104
+ # --- DSL ---
105
+
106
+ command :health, description: 'Check Orchestrator API health', setup: :setup_api
107
+ command :info, description: 'Ping the remote Orchestrator instance', setup: :setup_api, action: ->{Result::SingleObject.new(call_ao('remote_node_ping', format: 'xml', xml_arrays: false))}
108
+ command :processes, description: 'Show Orchestrator background process status', setup: :setup_api, action: ->{Result::ObjectList.new(call_ao('processes_status', format: 'xml')['process'])}
109
+ command :monitors, description: 'Show Orchestrator monitor snapshot', setup: :setup_api, action: ->{Result::SingleObject.new(call_ao('monitor_snapshot')['monitor'])}
110
+ command :plugins, description: 'Show Orchestrator plugin versions', setup: :setup_api, action: ->{Result::ObjectList.new(call_ao('plugin_version')['Plugin'])}
111
+ command :workflows, description: 'Manage workflows', setup: :setup_api
112
+ command :workorders, description: 'Manage work orders', setup: :setup_api
113
+ command :workstep, description: 'Manage work steps', setup: :setup_api
114
+
115
+ commands_under(:workflows) do
116
+ command(:list, description: 'List all workflows', action: lambda do
117
+ Result::ObjectList.new(
118
+ call_ao('workflows_list')['workflows']['workflow'],
119
+ fields: %w[id portable_id name published_status published_revision_id latest_revision_id last_modification]
120
+ )
121
+ end)
122
+ command :status, description: 'Check running status of workflow(s)',
123
+ arguments: [{name: :wf_id, type: :identifier}],
124
+ action: ->(wf_id:, **){Result::ObjectList.new(call_ao(wf_id.eql?(SpecialValues::ALL) ? 'workflows_status' : "workflows_status/#{wf_id}")['workflows']['workflow'])}
125
+ command :inputs, description: 'Fetch input specification for a workflow',
126
+ arguments: [{name: :wf_id, type: :identifier}],
127
+ action: ->(wf_id:, **){Result::SingleObject.new(call_ao("workflow_inputs_spec/#{wf_id}")['workflow_inputs_spec'])}
128
+ command :details, description: 'Check detailed running status of a workflow',
129
+ arguments: [{name: :wf_id, type: :identifier}],
130
+ action: ->(wf_id:, **){Result::ObjectList.new(call_ao("workflow_details/#{wf_id}")['workflows']['workflow']['statuses'])}
131
+ command :start, description: 'Initiate a work order (sync or async)',
132
+ arguments: [{name: :wf_id, type: :identifier}, {name: :external_parameters, type: Hash, mandatory: false, default: {}}]
133
+ command :export, description: 'Export a workflow',
134
+ arguments: [{name: :wf_id, type: :identifier}],
135
+ action: ->(wf_id:, **){Result::Text.new(call_ao("export_workflow/#{wf_id}", format: nil, http: true).body)}
136
+ command :workorders, description: 'Fetch all work orders from a workflow',
137
+ arguments: [{name: :wf_id, type: :identifier}],
138
+ action: ->(wf_id:, **){Result::ObjectList.new(call_ao("work_orders_list/#{wf_id}")['work_orders'])}
139
+ command :outputs, description: 'Fetch output specification for a workflow',
140
+ arguments: [{name: :wf_id, type: :identifier}],
141
+ action: ->(wf_id:, **){Result::ObjectList.new(call_ao("workflow_outputs_spec/#{wf_id}")['workflow_outputs_spec']['output'])}
142
+ end
101
143
 
102
- def execute_action
144
+ commands_under(:workorders) do
145
+ command :status, description: 'Check the status of a work order',
146
+ arguments: [{name: :wo_id, type: :identifier}],
147
+ action: ->(wo_id:, **){Result::SingleObject.new(call_ao("work_order_status/#{wo_id}")['work_order'])}
148
+ command :cancel, description: 'Cancel a work order',
149
+ arguments: [{name: :wo_id, type: :identifier}],
150
+ action: ->(wo_id:, **){Result::SingleObject.new(call_ao("work_order_cancel/#{wo_id}")['work_order'])}
151
+ command :reset, description: 'Reset a work order',
152
+ arguments: [{name: :wo_id, type: :identifier}],
153
+ action: ->(wo_id:, **){Result::SingleObject.new(call_ao("work_order_reset/#{wo_id}")['work_order'])}
154
+ command :output, description: 'Fetch output of a work order',
155
+ arguments: [{name: :wo_id, type: :identifier}],
156
+ action: ->(wo_id:, **){Result::ObjectList.new(call_ao("work_order_output/#{wo_id}", format: 'xml')['variable'])}
157
+ end
158
+
159
+ commands_under(:workstep) do
160
+ command :status, description: 'Check the status of a work step',
161
+ arguments: [{name: :ws_id, type: :identifier}],
162
+ action: ->(ws_id:, **){Result::SingleObject.new(call_ao("work_step_status/#{ws_id}"))}
163
+ command :cancel, description: 'Cancel a work step',
164
+ arguments: [{name: :ws_id, type: :identifier}],
165
+ action: ->(ws_id:, **){Result::SingleObject.new(call_ao("work_step_cancel/#{ws_id}"))}
166
+ end
167
+
168
+ # --- setup ---
169
+
170
+ # Build the Orchestrator REST API from CLI options.
171
+ # @return [Hash] ctx with no extra keys (stores api in @api_orch instance var)
172
+ def setup_api(**)
103
173
  auth_params =
104
174
  case options.get_option(:auth_style, mandatory: true)
105
175
  when :arg_pass
@@ -119,145 +189,47 @@ module Aspera
119
189
  when :apikey
120
190
  Aspera.error_not_implemented
121
191
  end
122
-
123
192
  @api_orch = Rest.new(
124
193
  base_url: options.get_option(:url, mandatory: true),
125
194
  auth: auth_params
126
195
  )
196
+ {}
197
+ end
127
198
 
128
- command1 = options.get_next_command(ACTIONS)
129
- case command1
130
- when :health
131
- nagios = Nagios.new
132
- begin
133
- info = call_ao('remote_node_ping', format: 'xml', xml_arrays: false)
134
- nagios.add_ok('api', 'accessible')
135
- nagios.check_product_version('api', 'orchestrator', info['orchestrator-version'])
136
- rescue StandardError => e
137
- nagios.add_critical('node api', e.to_s)
138
- end
139
- Main.result_object_list(nagios.status_list)
140
- # 14. Ping the remote Instance
141
- when :info
142
- result = call_ao('remote_node_ping', format: 'xml', xml_arrays: false)
143
- return Main.result_single_object(result)
144
- # 12. Orchestrator Background Process status
145
- when :processes
146
- # TODO: Bug ? API has only XML format
147
- result = call_ao('processes_status', format: 'xml')
148
- return Main.result_object_list(result['process'])
149
- # 13. Orchestrator Monitor
150
- when :monitors
151
- result = call_ao('monitor_snapshot')
152
- return Main.result_single_object(result['monitor'])
153
- when :plugins
154
- # TODO: Bug ? only json format on url
155
- result = call_ao('plugin_version')
156
- return Main.result_object_list(result['Plugin'])
157
- when :workflows
158
- command = options.get_next_command(%i[list status inputs details start export workorders outputs])
159
- case command
160
- # 1. List all available workflows on the system
161
- when :list
162
- result = call_ao('workflows_list')
163
- return Main.result_object_list(result['workflows']['workflow'], fields: %w[id portable_id name published_status published_revision_id latest_revision_id last_modification])
164
- # 2.1 Initiate a workorder - Asynchronous
165
- # 2.2 Initiate a workorder - Synchronous
166
- when :start
167
- result = {
168
- type: :single_object,
169
- data: nil
170
- }
171
- call_params = {format: :json}
172
- wf_id = options.instance_identifier
173
- # get external parameters if any
174
- options.get_next_argument('external_parameters', mandatory: false, validation: Hash, default: {}).each do |name, value|
175
- call_params["external_parameters[#{name}]"] = value
176
- end
177
- # synchronous call ?
178
- call_params['synchronous'] = true if options.get_option(:synchronous, mandatory: true)
179
- # expected result for synchro call ?
180
- result_location = options.get_option(:result)
181
- unless result_location.nil?
182
- result[:type] = :status
183
- fields = result_location.split(':')
184
- raise Cli::BadArgument, "Expects: work_step:result_name : #{result_location}" if fields.length != 2
185
- call_params['explicit_output_step'] = fields[0]
186
- call_params['explicit_output_variable'] = fields[1]
187
- # implicitly, call is synchronous
188
- call_params['synchronous'] = true
189
- end
190
- result[:type] = :text if call_params['synchronous']
191
- result[:data] = call_ao("initiate/#{wf_id}", args: call_params)
192
- return result
193
- # 3. Fetch input specification for a workflow
194
- when :inputs
195
- result = call_ao("workflow_inputs_spec/#{options.instance_identifier}")
196
- return Main.result_single_object(result['workflow_inputs_spec'])
197
- # 4. Check the running status for all workflows
198
- # 5. Check the running status for a particular workflow
199
- when :status
200
- wf_id = options.instance_identifier
201
- result = call_ao(wf_id.eql?(SpecialValues::ALL) ? 'workflows_status' : "workflows_status/#{wf_id}")
202
- return Main.result_object_list(result['workflows']['workflow'])
203
- # 6. Check the detailed running status for a particular workflow
204
- when :details
205
- result = call_ao("workflow_details/#{options.instance_identifier}")
206
- return Main.result_object_list(result['workflows']['workflow']['statuses'])
207
- # 15. Fetch output specification for a particular work flow
208
- when :outputs
209
- result = call_ao("workflow_outputs_spec/#{options.instance_identifier}")
210
- return Main.result_object_list(result['workflow_outputs_spec']['output'])
211
- # 19.Fetch all workorders from a workflow
212
- when :workorders
213
- result = call_ao("work_orders_list/#{options.instance_identifier}")
214
- return Main.result_object_list(result['work_orders'])
215
- when :export
216
- result = call_ao("export_workflow/#{options.instance_identifier}", format: nil, http: true)
217
- return Main.result_text(result.body)
218
- end
219
- when :workorders
220
- command = options.get_next_command(%i[status cancel reset output])
221
- case command
222
- # 7. Check the status for a particular work order
223
- when :status
224
- wo_id = options.instance_identifier
225
- result = call_ao("work_order_status/#{wo_id}")
226
- return Main.result_single_object(result['work_order'])
227
- # 9. Cancel a Work Order
228
- when :cancel
229
- wo_id = options.instance_identifier
230
- result = call_ao("work_order_cancel/#{wo_id}")
231
- return Main.result_single_object(result['work_order'])
232
- # 11. Reset a Work order
233
- when :reset
234
- wo_id = options.instance_identifier
235
- result = call_ao("work_order_reset/#{wo_id}")
236
- return Main.result_single_object(result['work_order'])
237
- # 16. Fetch output of a work order
238
- when :output
239
- wo_id = options.instance_identifier
240
- result = call_ao("work_order_output/#{wo_id}", format: 'xml')
241
- return Main.result_object_list(result['variable'])
242
- end
243
- when :workstep
244
- command = options.get_next_command(%i[status cancel])
245
- case command
246
- # 8. Check the status of a Step
247
- when :status
248
- ws_id = options.instance_identifier
249
- result = call_ao("work_step_status/#{ws_id}")
250
- return Main.result_single_object(result)
251
- # 10. Cancel a Work Step
252
- when :cancel
253
- ws_id = options.instance_identifier
254
- result = call_ao("work_step_cancel/#{ws_id}")
255
- return Main.result_single_object(result)
256
- end
257
- else Aspera.error_unexpected_value(command)
199
+ def action_health
200
+ nagios = Nagios.new
201
+ begin
202
+ info = call_ao('remote_node_ping', format: 'xml', xml_arrays: false)
203
+ nagios.add_ok('api', 'accessible')
204
+ nagios.check_product_version('api', 'orchestrator', info['orchestrator-version'])
205
+ rescue StandardError => e
206
+ nagios.add_critical('node api', e.to_s)
258
207
  end
208
+ Result::ObjectList.new(nagios.status_list)
209
+ end
210
+
211
+ # 2.1/2.2 Initiate a workorder (async / synchronous)
212
+ def action_workflows_start(wf_id:, external_parameters:, **)
213
+ call_params = {format: :json}
214
+ # get external parameters if any
215
+ external_parameters.each do |name, value|
216
+ call_params["external_parameters[#{name}]"] = value
217
+ end
218
+ # synchronous call ?
219
+ call_params['synchronous'] = true if options.get_option(:synchronous, mandatory: true)
220
+ # expected result for synchro call ?
221
+ result_location = options.get_option(:result)
222
+ unless result_location.nil?
223
+ fields = result_location.split(':')
224
+ Aspera.assert(fields.length == 2, type: Cli::BadArgument){"Expects: work_step:result_name : #{result_location}"}
225
+ call_params['explicit_output_step'] = fields[0]
226
+ call_params['explicit_output_variable'] = fields[1]
227
+ # implicitly, call is synchronous
228
+ call_params['synchronous'] = true
229
+ end
230
+ result_data = call_ao("initiate/#{wf_id}", args: call_params)
231
+ call_params['synchronous'] ? Result::Text.new(result_data) : Result::SingleObject.new(result_data)
259
232
  end
260
- private :call_ao
261
233
  end
262
234
  end
263
235
  end