aspera-cli 4.3.0 → 4.4.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.
data/docs/doc_tools.rb ADDED
@@ -0,0 +1,58 @@
1
+ # get transfer spec parameter description
2
+ $LOAD_PATH.unshift(ENV["INCL_DIR_GEM"])
3
+ require 'aspera/fasp/parameters'
4
+
5
+ # check that required env vars exist, and files
6
+ %w{EXENAME GEMSPEC INCL_USAGE INCL_COMMANDS INCL_ASESSION INCL_DIR_GEM}.each do |e|
7
+ raise "missing env var #{e}" unless ENV.has_key?(e)
8
+ raise "missing file #{ENV[e]}" unless File.exist?(ENV[e]) or !e.start_with?('INCL_')
9
+ end
10
+
11
+ # set values used in ERB
12
+ # just command name
13
+ def cmd;ENV['EXENAME'];end
14
+
15
+ # used in text with formatting of command
16
+ def tool;'`'+cmd+'`';end
17
+
18
+ # prefix for env vars
19
+ def evp;cmd.upcase+'_';end
20
+
21
+ # just the name for "option preset"
22
+ def opprst;'option preset';end
23
+
24
+ # name with link
25
+ def prst;'['+opprst+'](#lprt)';end
26
+
27
+ # name with link (plural)
28
+ def prsts;'['+opprst+'s](#lprt)';end
29
+
30
+ # in title
31
+ def prstt;opprst.capitalize;end
32
+
33
+ def gemspec;Gem::Specification::load(ENV['GEMSPEC']) or raise "error loading #{ENV["GEMSPEC"]}";end
34
+
35
+ def geminstadd;gemspec.version.to_s.match(/\.[^0-9]/)?' --pre':'';end
36
+
37
+ # transfer spec description generation
38
+ def spec_table
39
+ r='<table><tr><th>Field</th><th>Type</th>'
40
+ Aspera::Fasp::Parameters::SUPPORTED_AGENTS_SHORT.each do |c|
41
+ r << '<th>'<<c.to_s.upcase<<'</th>'
42
+ end
43
+ r << '<th>Description</th></tr>'
44
+ Aspera::Fasp::Parameters.man_table.each do |p|
45
+ p[:description] << (p[:description].empty? ? '' : "\n") << "(" << p[:cli] << ")" unless p[:cli].to_s.empty?
46
+ p.delete(:cli)
47
+ p.keys.each{|c|p[c]='&nbsp;' if p[c].to_s.empty?}
48
+ p[:description].gsub!("\n",'<br/>')
49
+ p[:type].gsub!(',','<br/>')
50
+ r << '<tr><td>'<<p[:name]<<'</td><td>'<<p[:type]<<'</td>'
51
+ Aspera::Fasp::Parameters::SUPPORTED_AGENTS_SHORT.each do |c|
52
+ r << '<td>'<<p[c]<<'</td>'
53
+ end
54
+ r << '<td>'<<p[:description]<<'</td></tr>'
55
+ end
56
+ r << '</table>'
57
+ return r
58
+ end
data/lib/aspera/aoc.rb CHANGED
@@ -2,6 +2,7 @@ require 'aspera/log'
2
2
  require 'aspera/rest'
3
3
  require 'aspera/hash_ext'
4
4
  require 'aspera/data_repository'
5
+ require 'aspera/node'
5
6
  require 'base64'
6
7
 
7
8
  module Aspera
@@ -24,9 +25,9 @@ module Aspera
24
25
  JWT_AUDIENCE='https://api.asperafiles.com/api/v1/oauth2/token'
25
26
  OAUTH_API_SUBPATH='api/v1/oauth2'
26
27
  DEFAULT_TSPEC_INFO={
27
- 'remote_user' => 'xfer',
28
- 'ssh_port' => 33001,
29
- 'fasp_port' => 33001
28
+ 'remote_user' => Node::ACCESS_KEY_TRANSFER_USER,
29
+ 'ssh_port' => Node::SSH_PORT_DEFAULT,
30
+ 'fasp_port' => Node::UDP_PORT_DEFAULT
30
31
  }
31
32
 
32
33
  private_constant :PRODUCT_NAME,:PROD_DOMAIN,:MAX_REDIRECT,:CLIENT_APPS,:PATHS_PUBLIC_LINK,:JWT_AUDIENCE,:OAUTH_API_SUBPATH,:DEFAULT_TSPEC_INFO
@@ -2,10 +2,15 @@ module Aspera
2
2
  module Cli
3
3
  # base class for plugins modules
4
4
  class Plugin
5
+ # operation without id
5
6
  GLOBAL_OPS=[:create,:list]
7
+ # operation on specific instance
6
8
  INSTANCE_OPS=[:modify,:delete,:show]
7
9
  ALL_OPS=[GLOBAL_OPS,INSTANCE_OPS].flatten
8
- #private_constant :GLOBAL_OPS,:INSTANCE_OPS,:ALL_OPS
10
+ # max number of items for list command
11
+ MAX_ITEMS='max'
12
+ # max number of pages for list command
13
+ MAX_PAGES='pmax'
9
14
 
10
15
  @@done=false
11
16
 
@@ -28,7 +33,7 @@ module Aspera
28
33
  end
29
34
  end
30
35
 
31
- def entity_command(command,rest_api,res_class_path,display_fields,id_symb,id_default=nil,subkey=false)
36
+ def entity_command(command,rest_api,res_class_path,display_fields,id_symb,id_default=nil,use_subkey=false)
32
37
  if INSTANCE_OPS.include?(command)
33
38
  begin
34
39
  one_res_id=self.options.get_option(id_symb,:mandatory)
@@ -54,10 +59,11 @@ module Aspera
54
59
  when :list
55
60
  resp=rest_api.read(res_class_path,parameters)
56
61
  data=resp[:data]
62
+ # TODO: not generic : which application is this for ?
57
63
  if resp[:http]['Content-Type'].start_with?('application/vnd.api+json')
58
- data=resp[:data][res_class_path]
64
+ data=data[res_class_path]
59
65
  end
60
- data=data[res_class_path] if subkey
66
+ data=data[res_class_path] if use_subkey
61
67
  return {:type => :object_list, :data=>data, :fields=>display_fields}
62
68
  when :modify
63
69
  property=self.options.get_option(:property,:optional)
@@ -74,12 +80,13 @@ module Aspera
74
80
  end
75
81
 
76
82
  # implement generic rest operations on given resource path
77
- def entity_action(rest_api,res_class_path,display_fields,id_symb,id_default=nil,subkey=false)
83
+ def entity_action(rest_api,res_class_path,display_fields,id_symb,id_default=nil,use_subkey=false)
78
84
  #res_name=res_class_path.gsub(%r{^.*/},'').gsub(%r{s$},'').gsub('_',' ')
79
85
  command=self.options.get_next_command(ALL_OPS)
80
- return entity_command(command,rest_api,res_class_path,display_fields,id_symb,id_default,subkey)
86
+ return entity_command(command,rest_api,res_class_path,display_fields,id_symb,id_default,use_subkey)
81
87
  end
82
88
 
89
+ # shortcuts for plugin environment
83
90
  def options; return @agents[:options];end
84
91
 
85
92
  def transfer; return @agents[:transfer];end
@@ -205,7 +205,7 @@ module Aspera
205
205
  node_api.call({:operation=>'GET',:subpath=>"files/#{node_file[:file_id]}/content",:save_to_file=>File.join(self.transfer.destination_folder('receive'),file_name)})
206
206
  return Main.result_status("downloaded: #{file_name}")
207
207
  when :v3
208
- # Note: other "common" actions are unauthorized with user scope
208
+ # Note: other common actions are unauthorized with user scope
209
209
  command_legacy=self.options.get_next_command(Node::SIMPLE_ACTIONS)
210
210
  # TODO: shall we support all methods here ? what if there is a link ?
211
211
  node_api=@api_aoc.get_node_api(top_node_file[:node_info],scope: AoC::SCOPE_NODE_USER)
@@ -224,14 +224,14 @@ module Aspera
224
224
  items=node_api.read("files/#{node_file[:file_id]}")[:data]
225
225
  return {:type=>:single_object,:data=>items}
226
226
  when :modify
227
- update_param=self.options.get_next_argument("update data (Hash)")
227
+ update_param=self.options.get_next_argument('update data (Hash)')
228
228
  res=node_api.update("files/#{node_file[:file_id]}",update_param)[:data]
229
229
  return {:type=>:single_object,:data=>res}
230
230
  when :permission
231
231
  command_perm=self.options.get_next_command([:list,:create])
232
232
  case command_perm
233
233
  when :list
234
- # generic options : TODO: as arg ?
234
+ # generic options : TODO: as arg ? option_url_query
235
235
  list_options||={'include'=>['[]','access_level','permission_count']}
236
236
  # special value: ALL will show all permissions
237
237
  if !VAL_ALL.eql?(node_file[:file_id])
@@ -239,11 +239,10 @@ module Aspera
239
239
  list_options['file_id']=node_file[:file_id]
240
240
  list_options['inherited']||=false
241
241
  end
242
- #option_url_query
243
242
  items=node_api.read('permissions',list_options)[:data]
244
243
  return {:type=>:object_list,:data=>items}
245
244
  when :create
246
- #create_param=self.options.get_next_argument("creation data (Hash)")
245
+ #create_param=self.options.get_next_argument('creation data (Hash)')
247
246
  set_workspace_info
248
247
  access_id="ASPERA_ACCESS_KEY_ADMIN_WS_#{@workspace_id}"
249
248
  node_file[:node_info]
@@ -266,14 +265,14 @@ module Aspera
266
265
  return {:type=>:single_object,:data=>item}
267
266
  else raise "internal error:shall not reach here (#{command_perm})"
268
267
  end
269
- raise "internal error:shall not reach here"
268
+ raise 'internal error:shall not reach here'
270
269
  else raise "internal error:shall not reach here (#{command_node_file})"
271
270
  end
272
- raise "internal error:shall not reach here"
271
+ raise 'internal error:shall not reach here'
273
272
  when :permissions
274
273
 
275
274
  end # command_repo
276
- raise "ERR"
275
+ raise 'ERR'
277
276
  end # execute_node_gen4_command
278
277
 
279
278
  # build constructor option list for AoC based on options of CLI
@@ -304,15 +303,15 @@ module Aspera
304
303
 
305
304
  ws_name=self.options.get_option(:workspace,:optional)
306
305
  if ws_name.nil?
307
- Log.log.debug("using default workspace".green)
306
+ Log.log.debug('using default workspace'.green)
308
307
  if @default_workspace_id.eql?(nil)
309
- raise CliError,"no default workspace defined for user, please specify workspace"
308
+ raise CliError,'no default workspace defined for user, please specify workspace'
310
309
  end
311
310
  # get default workspace
312
311
  @workspace_id=@default_workspace_id
313
312
  else
314
313
  # lookup another workspace
315
- wss=@api_aoc.read("workspaces",{'q'=>ws_name})[:data]
314
+ wss=@api_aoc.read('workspaces',{'q'=>ws_name})[:data]
316
315
  wss=wss.select { |i| i['name'].eql?(ws_name) }
317
316
  case wss.length
318
317
  when 0
@@ -320,14 +319,14 @@ module Aspera
320
319
  when 1
321
320
  @workspace_id=wss.first['id']
322
321
  else
323
- raise "unexpected case"
322
+ raise 'unexpected case'
324
323
  end
325
324
  end
326
325
  @workspace_data=@api_aoc.read("workspaces/#{@workspace_id}")[:data]
327
326
  Log.log.debug("workspace_id=#{@workspace_id},@workspace_data=#{@workspace_data}".red)
328
327
 
329
328
  @workspace_name||=@workspace_data['name']
330
- Log.log.info("current workspace is "+@workspace_name.red)
329
+ Log.log.info('current workspace is '+@workspace_name.red)
331
330
 
332
331
  # display workspace
333
332
  self.format.display_status("Current Workspace: #{@workspace_name.red}#{@workspace_id == @default_workspace_id ? ' (default)' : ''}")
@@ -343,7 +342,7 @@ module Aspera
343
342
  end
344
343
  home_node_id||=@workspace_data['home_node_id']||@workspace_data['node_id']
345
344
  home_file_id||=@workspace_data['home_file_id']
346
- raise "node_id must be defined" if home_node_id.to_s.empty?
345
+ raise 'node_id must be defined' if home_node_id.to_s.empty?
347
346
  @home_node_file={
348
347
  node_info: @api_aoc.read("nodes/#{home_node_id}")[:data],
349
348
  file_id: home_file_id
@@ -355,7 +354,7 @@ module Aspera
355
354
 
356
355
  def do_bulk_operation(ids_or_one,success_msg,id_result='id',&do_action)
357
356
  ids_or_one=[ids_or_one] unless self.options.get_option(:bulk)
358
- raise "expecting Array" unless ids_or_one.is_a?(Array)
357
+ raise 'expecting Array' unless ids_or_one.is_a?(Array)
359
358
  result_list=[]
360
359
  ids_or_one.each do |id|
361
360
  one={id_result=>id}
@@ -411,7 +410,8 @@ module Aspera
411
410
 
412
411
  # private
413
412
  def option_url_query(default)
414
- query=self.options.get_option(:query,:optional)||default
413
+ query=self.options.get_option(:query,:optional)
414
+ query=default if query.nil?
415
415
  Log.log.debug("Query=#{query}".bg_red)
416
416
  begin
417
417
  # check it is suitable
@@ -428,6 +428,37 @@ module Aspera
428
428
  end
429
429
  end
430
430
 
431
+ # Call @api_aoc.read with same parameters, but use paging if necessary to get all results
432
+ def read_with_paging(resource_class_path,base_query)
433
+ raise "Query must be Hash" unless base_query.is_a?(Hash)
434
+ # set default large page if user does not specify own parameters. AoC Caps to 1000 anyway
435
+ base_query['per_page']=1000 unless base_query.has_key?('per_page')
436
+ max_items=base_query[MAX_ITEMS]
437
+ base_query.delete(MAX_ITEMS)
438
+ max_pages=base_query[MAX_PAGES]
439
+ base_query.delete(MAX_PAGES)
440
+ item_list=[]
441
+ total_count=nil
442
+ current_page=base_query['page']
443
+ current_page=1 if current_page.nil?
444
+ page_count=0
445
+ loop do
446
+ query=base_query.clone
447
+ query['page']=current_page
448
+ result=@api_aoc.read(resource_class_path,query)
449
+ total_count=result[:http]['X-Total-Count']
450
+ page_count+=1
451
+ current_page+=1
452
+ add_items=result[:data]
453
+ break if add_items.empty?
454
+ # append new items to full list
455
+ item_list += add_items
456
+ break if !max_pages.nil? and page_count > max_pages
457
+ break if !max_items.nil? and item_list.count > max_items
458
+ end
459
+ return item_list,total_count
460
+ end
461
+
431
462
  def execute_admin_action
432
463
  @api_aoc.oauth.params[:scope]=AoC::SCOPE_FILES_ADMIN
433
464
  command_admin=self.options.get_next_command([ :ats, :resource, :usage_reports, :analytics, :subscription, :auth_providers ])
@@ -517,11 +548,11 @@ module Aspera
517
548
  when 'organizations'; c_user_info['organization_id']
518
549
  when 'users'; c_user_info['id']
519
550
  when 'nodes'; c_user_info['id']
520
- else raise "organizations or users for option --name"
551
+ else raise 'organizations or users for option --name'
521
552
  end
522
553
  #
523
554
  filter=self.options.get_option(:query,:optional) || {}
524
- raise "query must be Hash" unless filter.is_a?(Hash)
555
+ raise 'query must be Hash' unless filter.is_a?(Hash)
525
556
  filter['limit']||=100
526
557
  if self.options.get_option(:once_only,:mandatory)
527
558
  saved_date=[]
@@ -547,13 +578,13 @@ module Aspera
547
578
  return {:type=>:object_list,:data=>events}
548
579
  end
549
580
  when :resource
550
- resource_type=self.options.get_next_argument('resource',[:self,:organization,:user,:group,:client,:contact,:dropbox,:node,:operation,:package,:saml_configuration, :workspace, :dropbox_membership,:short_link,:workspace_membership,:apps_new,:client_registration_token,:client_access_key,:kms_profile])
581
+ resource_type=self.options.get_next_argument('resource',[:self,:organization,:user,:group,:client,:contact,:dropbox,:node,:operation,:package,:saml_configuration, :workspace, :dropbox_membership,:short_link,:workspace_membership,:application,:client_registration_token,:client_access_key,:kms_profile])
551
582
  # get path on API
552
583
  resource_class_path=case resource_type
553
584
  when :self,:organization
554
- "#{resource_type}"
555
- when :apps_new
556
- "admin/#{resource_type}"
585
+ resource_type
586
+ when :application
587
+ 'admin/apps_new'
557
588
  when :dropbox
558
589
  resource_type.to_s+'es'
559
590
  when :client_registration_token,:client_access_key
@@ -582,13 +613,13 @@ module Aspera
582
613
  res_id=@home_node_file[:node_info]['id']
583
614
  end
584
615
  if !res_name.nil?
585
- Log.log.warn("name overrides id") unless res_id.nil?
616
+ Log.log.warn('name overrides id') unless res_id.nil?
586
617
  matching=@api_aoc.read(resource_class_path,{:q=>res_name})[:data]
587
- raise CliError,"no resource match name" if matching.empty?
618
+ raise CliError,'no resource match name' if matching.empty?
588
619
  raise CliError,"several resources match name (#{matching.join(',')})" unless matching.length.eql?(1)
589
620
  res_id=matching.first['id']
590
621
  end
591
- raise CliBadArgument,"provide either id or name" if res_id.nil?
622
+ raise CliBadArgument,'provide either id or name' if res_id.nil?
592
623
  resource_instance_path="#{resource_class_path}/#{res_id}"
593
624
  end
594
625
  resource_instance_path=resource_class_path if singleton_object
@@ -598,26 +629,29 @@ module Aspera
598
629
  id_result='token' if resource_class_path.eql?('admin/client_registration_tokens')
599
630
  # TODO: report inconsistency: creation url is !=, and does not return id.
600
631
  resource_class_path='admin/client_registration/token' if resource_class_path.eql?('admin/client_registration_tokens')
601
- list_or_one=self.options.get_next_argument("creation data (Hash)")
632
+ list_or_one=self.options.get_next_argument('creation data (Hash)')
602
633
  return do_bulk_operation(list_or_one,'created',id_result)do|params|
603
- raise "expecting Hash" unless params.is_a?(Hash)
634
+ raise 'expecting Hash' unless params.is_a?(Hash)
604
635
  @api_aoc.create(resource_class_path,params)[:data]
605
636
  end
606
637
  when :list
607
- default_fields=['id','name']
608
- list_query=nil
638
+ default_fields=['id']
639
+ default_query={}
609
640
  case resource_type
610
- when :node; default_fields.push('host','access_key')
641
+ when :application; default_query={:organization_apps=>true};default_fields.push('app_type','app_name','available','direct_authorizations_allowed','workspace_authorizations_allowed')
642
+ when :client,:client_access_key,:dropbox,:group,:package,:saml_configuration,:workspace; default_fields.push('name')
643
+ when :client_registration_token; default_fields.push('value','data.client_subject_scopes','created_at')
644
+ when :contact; default_fields=['email','name','source_id','source_type']
645
+ when :node; default_fields.push('name','host','access_key')
611
646
  when :operation; default_fields=nil
612
- when :contact; default_fields=["email","name","source_id","source_type"]
613
- when :apps_new; list_query={:organization_apps=>true};default_fields=['app_type','available']
614
- when :client_registration_token; default_fields=['id','value','data.client_subject_scopes','created_at']
647
+ when :short_link; default_fields.push('short_url','data.url_token_data.purpose')
648
+ when :user; default_fields.push('name','email')
615
649
  end
616
- result=@api_aoc.read(resource_class_path,option_url_query(list_query))
617
- count_msg="Items: #{result[:data].length}/#{result[:http]['X-Total-Count']}"
618
- count_msg=count_msg.bg_red unless result[:data].length.eql?(result[:http]['X-Total-Count'].to_i)
650
+ item_list,total_count=read_with_paging(resource_class_path,option_url_query(default_query))
651
+ count_msg="Items: #{item_list.length}/#{total_count}"
652
+ count_msg=count_msg.bg_red unless item_list.length.eql?(total_count.to_i)
619
653
  self.format.display_status(count_msg)
620
- return {:type=>:object_list,:data=>result[:data],:fields=>default_fields}
654
+ return {:type=>:object_list,:data=>item_list,:fields=>default_fields}
621
655
  when :show
622
656
  object=@api_aoc.read(resource_instance_path)[:data]
623
657
  fields=object.keys.select{|k|!k.eql?('certificate')}
@@ -647,8 +681,8 @@ module Aspera
647
681
  when :shared_folders
648
682
  read_params = case resource_type
649
683
  when :workspace;{'access_id'=>"ASPERA_ACCESS_KEY_ADMIN_WS_#{res_id}",'access_type'=>'user'}
650
- when :node;{'include'=>['[]','access_level','permission_count'],'created_by_id'=>"ASPERA_ACCESS_KEY_ADMIN"}
651
- else raise "error"
684
+ when :node;{'include'=>['[]','access_level','permission_count'],'created_by_id'=>'ASPERA_ACCESS_KEY_ADMIN'}
685
+ else raise 'error'
652
686
  end
653
687
  res_data=@api_aoc.read("#{resource_class_path}/#{res_id}/permissions",read_params)[:data]
654
688
  fields=case resource_type
@@ -688,7 +722,7 @@ module Aspera
688
722
  create_data.deep_merge!(user_create_data)
689
723
  Log.dump(:data,create_data)
690
724
  raise :ERROR
691
- else raise "unknown command"
725
+ else raise 'unknown command'
692
726
  end
693
727
  when :usage_reports
694
728
  return {:type=>:object_list,:data=>@api_aoc.read('usage_reports',{:workspace_id=>@workspace_id})[:data]}
@@ -719,7 +753,7 @@ module Aspera
719
753
  when :workspaces
720
754
  return {:type=>:object_list,:data=>@api_aoc.read('workspaces')[:data],:fields=>['id','name']}
721
755
  # when :settings
722
- # return {:type=>:object_list,:data=>@api_aoc.read("client_settings/")[:data]}
756
+ # return {:type=>:object_list,:data=>@api_aoc.read('client_settings/')[:data]}
723
757
  when :shared_inboxes
724
758
  query=option_url_query(nil)
725
759
  if query.nil?
@@ -764,7 +798,7 @@ module Aspera
764
798
  resolve_package_recipients(package_creation,'recipients')
765
799
  resolve_package_recipients(package_creation,'bcc_recipients')
766
800
 
767
- # create a new package with one file
801
+ # create a new package container
768
802
  package_info=@api_aoc.create('packages',package_creation)[:data]
769
803
 
770
804
  # get node information for the node on which package must be created
@@ -775,7 +809,7 @@ module Aspera
775
809
 
776
810
  # execute transfer
777
811
  node_file = {node_info: node_info, file_id: package_info['contents_file_id']}
778
- # raise esception if at least one error
812
+ # raise exception if at least one error
779
813
  Main.result_transfer(transfer_start(AoC::PACKAGES_APP,'send',node_file,AoC.package_tags(package_info,'upload')))
780
814
  # return all info on package
781
815
  return { :type=>:single_object, :data =>package_info}
@@ -826,8 +860,10 @@ module Aspera
826
860
  package_info=@api_aoc.read("packages/#{package_id}")[:data]
827
861
  return { :type=>:single_object, :data =>package_info }
828
862
  when :list
829
- # list all packages ('page'=>1,'per_page'=>10,)'sort'=>'-sent_at',
830
- packages=@api_aoc.read('packages',{'archived'=>false,'exclude_dropbox_packages'=>true,'has_content'=>true,'received'=>true,'workspace_id'=>@workspace_id})[:data]
863
+ query=option_url_query({'archived'=>false,'exclude_dropbox_packages'=>true,'has_content'=>true,'received'=>true})
864
+ raise 'option must be Hash' unless query.is_a?(Hash)
865
+ query['workspace_id']||=@workspace_id
866
+ packages=@api_aoc.read('packages',query)[:data]
831
867
  return {:type=>:object_list,:data=>packages,:fields=>['id','name','bytes_transferred']}
832
868
  when :delete
833
869
  list_or_one=self.options.get_option(:id,:mandatory)
@@ -910,9 +946,9 @@ module Aspera
910
946
  end
911
947
  return result
912
948
  end # files command
913
- throw "Error: shall not reach this line"
949
+ throw 'Error: shall not reach this line'
914
950
  when :automation
915
- Log.log.warn("BETA: work under progress")
951
+ Log.log.warn('BETA: work under progress')
916
952
  # automation api is not in the same place
917
953
  automation_rest_params=@api_aoc.params.clone
918
954
  automation_rest_params[:base_url].gsub!('/api/','/automation/')
@@ -935,9 +971,9 @@ module Aspera
935
971
  wf_command=self.options.get_next_command([:list,:create,:show])
936
972
  wf_id=self.options.get_option(:id,:mandatory)
937
973
  step=automation_api.create('steps',{'workflow_id'=>wf_id})[:data]
938
- automation_api.update("workflows/#{wf_id}",{'step_order'=>[step["id"]]})
939
- action=automation_api.create('actions',{'step_id'=>step["id"],'type'=>'manual'})[:data]
940
- automation_api.update("steps/#{step["id"]}",{'action_order'=>[action["id"]]})
974
+ automation_api.update("workflows/#{wf_id}",{'step_order'=>[step['id']]})
975
+ action=automation_api.create('actions',{'step_id'=>step['id'],'type'=>'manual'})[:data]
976
+ automation_api.update("steps/#{step['id']}",{'action_order'=>[action['id']]})
941
977
  wf=automation_api.read("workflows/#{wf_id}")[:data]
942
978
  return {:type=>:single_object,:data=>wf}
943
979
  end
@@ -953,7 +989,7 @@ module Aspera
953
989
  else
954
990
  raise "internal error: #{command}"
955
991
  end # action
956
- raise RuntimeError, "internal error: command shall return"
992
+ raise RuntimeError, 'internal error: command shall return'
957
993
  end
958
994
 
959
995
  private :c_user_info,:aoc_params,:set_workspace_info,:set_home_node_file,:do_bulk_operation,:resolve_package_recipients,:option_url_query,:assert_public_link_types,:execute_admin_action