Class: Aspera::Cli::Plugins::Node
- Includes:
- SyncActions
- Defined in:
- lib/aspera/cli/plugins/node.rb
Constant Summary collapse
- COMMANDS_GEN3_SPEC =
DSL metadata for Gen3 root commands (description:, arguments:, transfer_paths:, aliases:). :access_keys is skipped (intermediate node declared separately), :sync is declared separately. action: entries are in GEN3_NODE_ACTIONS, or implicit.
{ search: {description: 'Search for files', arguments: [{name: :path}]}, space: {description: 'Show space information', arguments: [{name: :paths, multiple: true}]}, mkdir: {description: 'Create a folder (Gen3)', arguments: [{name: :paths, multiple: true}]}, mklink: {description: 'Create a symbolic link (Gen3)', arguments: [{name: :target}, {name: :link_path}]}, mkfile: {description: 'Create a file (Gen3)', arguments: [{name: :path}, {name: :contents, mandatory: false, default: nil}]}, rename: {description: 'Rename a file or folder (Gen3)', arguments: [{name: :folder}, {name: :source}, {name: :destination}]}, delete: {description: 'Delete files or folders (Gen3)', arguments: [{name: :paths, multiple: true}]}, ls: {description: 'List files (Gen3)', arguments: [{name: :path}], aliases: [:browse]}, upload: {description: 'Upload files (Gen3)', transfer_paths: :send}, download: {description: 'Download files (Gen3)', transfer_paths: :receive}, cat: {description: 'Show file contents (Gen3)', arguments: [{name: :path}]}, transport: {description: 'Show transport parameters'}, spec: {description: 'Show transfer spec base'}, api_details: {description: 'Show API details'}, health: {description: 'Check node health'}, events: {description: 'List events'}, info: {description: 'Show node info'}, slash: {description: 'Show root info'}, license: {description: 'Show license'}, access_keys: {description: 'Manage access keys'} }.freeze
- NODE4_READ_ACTIONS =
Gen4 read commands also exposed on AoC packages (
aoc packages ls <id>) %i[bearer_token_node node_info ls find].freeze
- COMMANDS_GEN4_SPEC =
{ mkdir: {description: 'Create folder', arguments: SINGLE_PATH_ARG}, mklink: {description: 'Create symbolic link', arguments: SINGLE_PATH_ARG}, mkfile: {description: 'Create file', arguments: [{name: :path}, {name: :contents, mandatory: false, default: nil}]}, rename: {description: 'Rename entry', arguments: [{name: :source_path}, {name: :new_name}]}, delete: {description: 'Delete entry', arguments: [{name: :path, bulk: true}]}, upload: {description: 'Upload files', transfer_paths: :send}, download: {description: 'Download files', transfer_paths: :receive}, modify: {description: 'Modify file', arguments: [{name: :path}, {name: :file, type: Hash, schema: 'node:components.schemas.files-id-put-request'}]}, cat: {description: 'Show file contents', arguments: SINGLE_PATH_ARG}, show: {description: 'Show file info', arguments: SINGLE_PATH_ARG}, thumbnail: {description: 'Show file thumbnail', arguments: SINGLE_PATH_ARG}, bearer_token_node: {description: 'Show bearer token for file node', arguments: SINGLE_PATH_ARG}, node_info: {description: 'Show node info for file', arguments: SINGLE_PATH_ARG}, ls: {description: 'List files', arguments: SINGLE_PATH_ARG, aliases: [:browse]}, find: {description: 'Find files', arguments: SINGLE_PATH_ARG + FILTER_ARGS} }.freeze
- COMMANDS_COS =
Root commands exposed by
cos nodeandshares files(mount: only:) %i[upload download info access_keys api_details transfer].freeze
- COMMANDS_SHARES =
%i[api_details space mkdir mklink mkfile rename delete ls upload download cat sync transport spec].freeze
- GEN4_LS_FIELDS =
browsedisplay fields for gen4 %w[name type recursive_size size modified_time access_level].freeze
Constants included from SyncActions
SyncActions::ADMIN_COMMANDS, SyncActions::PATH_AND_INFO_ARGS, SyncActions::STATE_STR
Constants inherited from Base
Instance Attribute Summary
Attributes inherited from Base
Class Method Summary collapse
- .detect(address_or_url) ⇒ Hash, NilClass
-
.gen3_entry_folder?(entry) ⇒ Boolean
Using /files/browse: is it a folder (node and shares).
Instance Method Summary collapse
- #action_access_keys_do_bearer_token_node(path:, do_root_file_id:) ⇒ Object
-
#action_access_keys_do_cat(path:, do_root_file_id:) ⇒ Object
access_keys > do > cat.
-
#action_access_keys_do_delete(path:, do_root_file_id:) ⇒ Object
access_keys > do > delete.
-
#action_access_keys_do_download(do_root_file_id:) ⇒ Object
access_keys > do > download.
-
#action_access_keys_do_find(path:, filter: nil, do_root_file_id:) ⇒ Object
access_keys > do > find.
-
#action_access_keys_do_ls(path:, do_root_file_id:) ⇒ Object
access_keys > do > ls.
- #action_access_keys_do_mkdir(path:, do_root_file_id:) ⇒ Object
- #action_access_keys_do_mkfile(path:, contents:, do_root_file_id:) ⇒ Object
- #action_access_keys_do_mklink(path:, do_root_file_id:) ⇒ Object
-
#action_access_keys_do_modify(path:, file:, do_root_file_id:) ⇒ Object
access_keys > do > modify.
- #action_access_keys_do_node_info(path:, do_root_file_id:) ⇒ Object
- #action_access_keys_do_permission_create(permission:, apifid:) ⇒ Object
- #action_access_keys_do_permission_delete(permission_id:, apifid:) ⇒ Object
-
#action_access_keys_do_permission_list(apifid:) ⇒ Object
access_keys > do > permission > list/show/create/modify/delete.
-
#action_access_keys_do_rename(source_path:, new_name:, do_root_file_id:) ⇒ Object
access_keys > do > rename.
-
#action_access_keys_do_show(path:, do_root_file_id:) ⇒ Object
access_keys > do > show.
-
#action_access_keys_do_thumbnail(path:, do_root_file_id:) ⇒ Object
access_keys > do > thumbnail.
-
#action_access_keys_do_upload(do_root_file_id:) ⇒ Object
access_keys > do > upload.
-
#action_access_keys_set_bearer_key(access_key_id:, bearer_key_pem:) ⇒ Object
access_keys > set_bearer_key.
- #action_asperabrowser ⇒ Object
- #action_async_bandwidth(async_id:) ⇒ Object
- #action_async_counters(async_id:) ⇒ Object
- #action_async_files(async_id:) ⇒ Object
-
#action_async_show(async_id:) ⇒ Object
async sub-commands: individual handlers.
- #action_cat(path:) ⇒ Object
-
#action_central_file_list(criteria:) ⇒ Object
central > file > list.
-
#action_central_file_modify(file:) ⇒ Object
central > file > modify.
-
#action_central_session_list(criteria:) ⇒ Object
central > session > list.
-
#action_delete(paths:) ⇒ Object
--- Handler methods (Gen3) ---.
- #action_download ⇒ Object
- #action_health ⇒ Object
- #action_mkdir(paths:) ⇒ Object
- #action_mkfile(path:, contents:) ⇒ Object
- #action_mklink(target:, link_path:) ⇒ Object
- #action_rename(folder:, source:, destination:) ⇒ Object
- #action_search(path:) ⇒ Object
- #action_simulator(parameters: {}) ⇒ Object
- #action_space(paths:) ⇒ Object
- #action_telemetry(parameters: {}) ⇒ Object
- #action_transfer_bandwidth_average ⇒ Object
-
#action_transfer_list ⇒ Object
transfer sub-commands.
- #action_transfer_sessions ⇒ Object
- #action_upload ⇒ Object
-
#api_node ⇒ Api::Node, Rest::Client
Node API: provided by the host plugin, or built from CLI options on first use.
-
#apifid_from_path(top_file_id, path) ⇒ Object
Resolve a NodeFileId from a path argument.
-
#async_lookup(field, value) ⇒ Integer
Search /async by name.
-
#browse_gen3(path) ⇒ Object
Gen3 API.
-
#central_validation ⇒ Object
central: shared helper.
-
#gen4_apifid_info(do_root_file_id, path) ⇒ Object
access_keys > do > node_info / bearer_token_node — shared helper builds the result hash.
-
#gen4_mk_resolve(top_file_id, path) ⇒ Array(NodeFileId, Hash)
access_keys > do > mkdir / mklink / mkfile — shared helper: resolve parent folder, build payload from query option, optionally check for name collision.
-
#initialize(context:, api: nil) ⇒ Node
constructor
A new instance of Node.
-
#lookup_access_key_self_id(field, value) ⇒ String
Lookup for access_keys: only supports %id:self selector.
-
#setup_access_key_do(access_key_id:) ⇒ Hash
access_keys > do - setup: resolve access key and root file id.
-
#setup_access_key_do_permission(do_root_file_id:, path:) ⇒ Hash
access_keys > do > permission - setup: resolve apifid from the path argument of the node do_root_file_id: comes from ctx (setup_access_key_do, or seed of a mount).
-
#setup_watch_folder ⇒ Object
watch_folder setup: inject required API header (avoids "Unable to convert 2016_09_14 configuration").
-
#ssync_lookup(field, value) ⇒ Integer
Search /asyncs by name.
-
#sync_gen3_block ⇒ Object
Obtains a transfer spec via the Node API for the given direction/folders.
-
#sync_gen4_block(do_root_file_id) ⇒ Object
Shared Gen4 sync block: obtains a transfer spec via the Gen4 API for the given direction/remote_path.
-
#sync_spec_request(sync_direction, local_path, remote_path) ⇒ Object
Create async transfer spec request from direction and folders.
-
#v3_node_plugin(do_root_file_id:) ⇒ Node
access_keys > do > v3 - mount target: Node plugin on the node hosting the root file.
-
#wizard(wizard, app_url) ⇒ Hash
:preset_value, :test_args.
Methods included from SyncActions
#action_sync_admin_file_info, #async_info_from_args, #db_from_args, included, register_sync_admin_commands, #run_sync_transfer
Methods inherited from BasicAuth
#basic_auth_api, #basic_auth_params
Methods inherited from Base
#action_for, #add_manual_header, application_name, #bulk_result, command, command_registry, commands_under, #config, crud_commands, declare_options, define_action_method, #dispatch_child, #dispatch_from_registry, #dispatch_leaf, #dispatch_mount, #entity_create, #entity_delete, #entity_list, #entity_modify, entity_noun, #entity_res_path, #entity_show, #execute_action, #execute_leaf, file_matcher, #formatter, #generate_help, #http_config, #invoke_action, operation_description, option_sources, option_specs, #options, #persistency, #presets, #progress_bar, #query_read_delete, register_option_spec, #resolve_argument, #resolve_arguments, #transfer, use_options, used_option_sources, #validate_registry
Methods included from OptionDeclarator
#declare_options, #option, #option_specs, #register_option_spec
Constructor Details
#initialize(context:, api: nil) ⇒ Node
Returns a new instance of Node.
170 171 172 173 174 |
# File 'lib/aspera/cli/plugins/node.rb', line 170 def initialize(context:, api: nil) super(context: context) # Api::Node or Rest::Client (Shares), when provided by the host plugin @api_node = api end |
Class Method Details
.detect(address_or_url) ⇒ Hash, NilClass
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/aspera/cli/plugins/node.rb', line 37 def detect(address_or_url) urls = if address_or_url.match?(%r{^[a-z]{1,6}://}) [address_or_url] else [ "https://#{address_or_url}", "https://#{address_or_url}:9092", "http://#{address_or_url}:9091" ] end error = nil urls.each do |base_url| next unless base_url.match?(%r{^https?://}) api = Rest::Client.new(base_url: base_url) test_endpoint = 'ping' http = api.read(test_endpoint, ret: :resp) next unless http.body.eql?('') # also remove "/" url_end = -2 - test_endpoint.length return { url: http.uri.to_s[0..url_end], version: 'requires authentication' } rescue StandardError => e error = e Log.log.debug { "detect error: #{e}" } end raise error if error return end |
.gen3_entry_folder?(entry) ⇒ Boolean
Using /files/browse: is it a folder (node and shares)
69 70 71 |
# File 'lib/aspera/cli/plugins/node.rb', line 69 def gen3_entry_folder?(entry) FOLDER_TYPES.include?(entry['type']) end |
Instance Method Details
#action_access_keys_do_bearer_token_node(path:, do_root_file_id:) ⇒ Object
871 872 873 874 875 876 877 |
# File 'lib/aspera/cli/plugins/node.rb', line 871 def action_access_keys_do_bearer_token_node(path:, do_root_file_id:, **) apifid, result = gen4_apifid_info(do_root_file_id, path) Log.dump(:result, result) Aspera.assert(apifid.node_api.auth_params[:type].eql?(:oauth2), type: BadArgument) { "Cannot get bearer token if authenticating with secret (#{apifid.node_api.auth_params[:type]})" } Aspera.assert(OAuth::Factory.bearer_auth?(result[:password]), 'Not using bearer token auth') Result::Text.new(result[:password]) end |
#action_access_keys_do_cat(path:, do_root_file_id:) ⇒ Object
access_keys > do > cat
772 773 774 775 |
# File 'lib/aspera/cli/plugins/node.rb', line 772 def action_access_keys_do_cat(path:, do_root_file_id:, **) apifid = apifid_from_path(do_root_file_id, path) Result::Text.new(apifid.node_api.read("files/#{apifid.file_id}/content", ret: :resp).body) end |
#action_access_keys_do_delete(path:, do_root_file_id:) ⇒ Object
access_keys > do > delete
804 805 806 807 808 809 810 811 812 813 814 815 |
# File 'lib/aspera/cli/plugins/node.rb', line 804 def action_access_keys_do_delete(path:, do_root_file_id:, **) bulk_result(path, command: :delete, id_result: 'path') do |l_path| apifid = if (m = Parser.percent_selector(l_path)) Aspera.assert_values(m[:field], ['id'], type: BadIdentifier) Api::NodeFileId.new(api_node, m[:value]) else api_node.resolve_api_fid(do_root_file_id, l_path) end apifid.node_api.delete("files/#{apifid.file_id}") {'path' => l_path} end end |
#action_access_keys_do_download(do_root_file_id:) ⇒ Object
access_keys > do > download
839 840 841 842 |
# File 'lib/aspera/cli/plugins/node.rb', line 839 def action_access_keys_do_download(do_root_file_id:, **) apifid, source_paths = api_node.resolve_api_fid_paths(do_root_file_id, transfer.ts_source_paths) Runner.result_transfer(transfer.start(apifid.node_api.transfer_spec_gen4(apifid.file_id, Transfer::Spec::DIRECTION_RECEIVE, {'paths'=>source_paths}))) end |
#action_access_keys_do_find(path:, filter: nil, do_root_file_id:) ⇒ Object
access_keys > do > find
766 767 768 769 |
# File 'lib/aspera/cli/plugins/node.rb', line 766 def action_access_keys_do_find(path:, filter: nil, do_root_file_id:, **) apifid = apifid_from_path(do_root_file_id, path) Result::ObjectList.new(api_node.find_files(apifid.file_id, Base.file_matcher(filter)), fields: ['path']) end |
#action_access_keys_do_ls(path:, do_root_file_id:) ⇒ Object
access_keys > do > ls
758 759 760 761 762 763 |
# File 'lib/aspera/cli/plugins/node.rb', line 758 def action_access_keys_do_ls(path:, do_root_file_id:, **) apifid = apifid_from_path(do_root_file_id, path) file_info = apifid.node_api.read("files/#{apifid.file_id}", headers: Api::Node.add_cache_control) return Result::ObjectList.new([file_info], fields: GEN4_LS_FIELDS) unless file_info['type'].eql?('folder') Result::ObjectList.new(apifid.node_api.list_files(apifid.file_id, query: query_read_delete), fields: GEN4_LS_FIELDS) end |
#action_access_keys_do_mkdir(path:, do_root_file_id:) ⇒ Object
908 909 910 911 912 |
# File 'lib/aspera/cli/plugins/node.rb', line 908 def action_access_keys_do_mkdir(path:, do_root_file_id:, **) apifid, payload = gen4_mk_resolve(do_root_file_id, path) payload[:type] = :folder Result::SingleObject.new(apifid.node_api.create("files/#{apifid.file_id}/files", payload)) end |
#action_access_keys_do_mkfile(path:, contents:, do_root_file_id:) ⇒ Object
922 923 924 925 926 927 |
# File 'lib/aspera/cli/plugins/node.rb', line 922 def action_access_keys_do_mkfile(path:, contents:, do_root_file_id:, **) apifid, payload = gen4_mk_resolve(do_root_file_id, path) payload[:type] = :file payload[:contents] = contents.nil? ? '' : Base64.strict_encode64(contents) Result::SingleObject.new(apifid.node_api.create("files/#{apifid.file_id}/files", payload)) end |
#action_access_keys_do_mklink(path:, do_root_file_id:) ⇒ Object
914 915 916 917 918 919 920 |
# File 'lib/aspera/cli/plugins/node.rb', line 914 def action_access_keys_do_mklink(path:, do_root_file_id:, **) apifid, payload = gen4_mk_resolve(do_root_file_id, path) payload[:type] = :link Aspera.assert(payload[:target_id], 'Missing target_id') Aspera.assert(payload[:target_node_id], 'Missing target_node_id') Result::SingleObject.new(apifid.node_api.create("files/#{apifid.file_id}/files", payload)) end |
#action_access_keys_do_modify(path:, file:, do_root_file_id:) ⇒ Object
access_keys > do > modify
784 785 786 787 788 |
# File 'lib/aspera/cli/plugins/node.rb', line 784 def action_access_keys_do_modify(path:, file:, do_root_file_id:, **) apifid = apifid_from_path(do_root_file_id, path) apifid.node_api.update("files/#{apifid.file_id}", file) Result::Status.new('Done') end |
#action_access_keys_do_node_info(path:, do_root_file_id:) ⇒ Object
866 867 868 869 |
# File 'lib/aspera/cli/plugins/node.rb', line 866 def action_access_keys_do_node_info(path:, do_root_file_id:, **) _apifid, result = gen4_apifid_info(do_root_file_id, path) Result::SingleObject.new(result) end |
#action_access_keys_do_permission_create(permission:, apifid:) ⇒ Object
947 948 949 950 951 952 953 954 955 956 957 |
# File 'lib/aspera/cli/plugins/node.rb', line 947 def (permission:, apifid:, **) create_param = Aspera.assert(!create_param.key?('file_id'), type: Cli::BadArgument) { 'no file_id' } create_param['file_id'] = apifid.file_id create_param['access_levels'] = Api::Node::ACCESS_LEVELS unless create_param.key?('access_levels') the_app = apifid.node_api.app_info the_app&.api&.(perm_data: create_param, app_info: the_app) created_data = apifid.node_api.create('permissions', create_param) the_app&.api&.(event_data: created_data, app_info: the_app) Result::SingleObject.new(created_data) end |
#action_access_keys_do_permission_delete(permission_id:, apifid:) ⇒ Object
938 939 940 941 942 943 944 945 |
# File 'lib/aspera/cli/plugins/node.rb', line 938 def (permission_id:, apifid:, **) bulk_result(, command: :delete) do |one_id| apifid.node_api.delete("permissions/#{one_id}") the_app = apifid.node_api.app_info the_app&.api&.(event_data: {}, app_info: the_app, types: ['permission.deleted']) {'id' => one_id} end end |
#action_access_keys_do_permission_list(apifid:) ⇒ Object
access_keys > do > permission > list/show/create/modify/delete
930 931 932 933 934 935 936 |
# File 'lib/aspera/cli/plugins/node.rb', line 930 def (apifid:, **) list_query = query_read_delete(default: Rest.php_style({'include' => %w[access_level permission_count]})) # Specify file to get permissions for unless not specified (then, get all permissions) list_query['file_id'] = apifid.file_id unless apifid.file_id.to_s.empty? list_query['inherited'] = false if list_query.key?('file_id') && !list_query.key?('inherited') Result::ObjectList.new(apifid.node_api.read_with_pages('permissions', list_query)) end |
#action_access_keys_do_rename(source_path:, new_name:, do_root_file_id:) ⇒ Object
access_keys > do > rename
797 798 799 800 801 |
# File 'lib/aspera/cli/plugins/node.rb', line 797 def action_access_keys_do_rename(source_path:, new_name:, do_root_file_id:, **) apifid = api_node.resolve_api_fid(do_root_file_id, source_path) apifid.node_api.update("files/#{apifid.file_id}", {name: new_name}) Result::Status.new("renamed to #{new_name}") end |
#action_access_keys_do_show(path:, do_root_file_id:) ⇒ Object
access_keys > do > show
778 779 780 781 |
# File 'lib/aspera/cli/plugins/node.rb', line 778 def action_access_keys_do_show(path:, do_root_file_id:, **) apifid = apifid_from_path(do_root_file_id, path) Result::SingleObject.new(apifid.node_api.read("files/#{apifid.file_id}")) end |
#action_access_keys_do_thumbnail(path:, do_root_file_id:) ⇒ Object
access_keys > do > thumbnail
791 792 793 794 |
# File 'lib/aspera/cli/plugins/node.rb', line 791 def action_access_keys_do_thumbnail(path:, do_root_file_id:, **) apifid = apifid_from_path(do_root_file_id, path) Result::Image.new(apifid.node_api.read("files/#{apifid.file_id}/preview", headers: {'Accept' => 'image/png'}, ret: :resp).body) end |
#action_access_keys_do_upload(do_root_file_id:) ⇒ Object
access_keys > do > upload
833 834 835 836 |
# File 'lib/aspera/cli/plugins/node.rb', line 833 def action_access_keys_do_upload(do_root_file_id:, **) apifid = api_node.resolve_api_fid(do_root_file_id, transfer.destination_folder(Transfer::Spec::DIRECTION_SEND), true) Runner.result_transfer(transfer.start(apifid.node_api.transfer_spec_gen4(apifid.file_id, Transfer::Spec::DIRECTION_SEND))) end |
#action_access_keys_set_bearer_key(access_key_id:, bearer_key_pem:) ⇒ Object
access_keys > set_bearer_key
960 961 962 963 964 965 966 |
# File 'lib/aspera/cli/plugins/node.rb', line 960 def action_access_keys_set_bearer_key(access_key_id:, bearer_key_pem:, **) access_key_id = api_node.read('access_keys/self')['id'] if access_key_id.eql?('self') key = OpenSSL::PKey.read(bearer_key_pem) key = key.public_key if key.private? api_node.update("access_keys/#{access_key_id}", {token_verification_key: key.to_pem}) Result::Status.new('public key updated') end |
#action_asperabrowser ⇒ Object
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 |
# File 'lib/aspera/cli/plugins/node.rb', line 1122 def action_asperabrowser(**) browse_params = { 'nodeUser' => .get_option(:username, mandatory: true), 'nodePW' => .get_option(:password, mandatory: true), 'nodeURL' => .get_option(:url, mandatory: true) } # encode parameters so that it looks good in url encoded_params = Base64.strict_encode64(Zlib::Deflate.deflate(JSON.generate(browse_params))).gsub(/=+$/, '').tr('+/', '-_').reverse Environment.instance.open_uri("#{.get_option(:asperabrowserurl)}?goto=#{encoded_params}") return Result::Status.new('done') end |
#action_async_bandwidth(async_id:) ⇒ Object
982 983 984 985 986 987 988 989 |
# File 'lib/aspera/cli/plugins/node.rb', line 982 def action_async_bandwidth(async_id:, **) Integer(async_id) post_data = {'syncs' => [async_id], 'seconds' => 100} resp = api_node.create('async/bandwidth', post_data) data = resp['bandwidth_data'] return Result::Empty.new if data.empty? Result::ObjectList.new(data.first[async_id]['data']) end |
#action_async_counters(async_id:) ⇒ Object
1016 1017 1018 1019 1020 1021 |
# File 'lib/aspera/cli/plugins/node.rb', line 1016 def action_async_counters(async_id:, **) Integer(async_id) resp = api_node.create('async/counters', {'syncs' => [async_id]})['sync_counters'].first[async_id].last return Result::Empty.new if resp.nil? Result::SingleObject.new(resp) end |
#action_async_files(async_id:) ⇒ Object
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 |
# File 'lib/aspera/cli/plugins/node.rb', line 991 def action_async_files(async_id:, **) Integer(async_id) post_data = {'syncs' => [async_id]} # not a URL query: merged into the POST body of async/files filter = .get_option(:query) post_data.merge!(filter) unless filter.nil? resp = api_node.create('async/files', post_data) data = resp['sync_files'] data = data.first[async_id] unless data.empty? iteration_data = [] skip_ids_persistency = nil if .get_option(:once_only, mandatory: true) skip_ids_persistency = PersistencyActionOnce.new( manager: persistency, data: iteration_data, id: IdGenerator.from_list('sync_files', .get_option(:url, mandatory: true), .get_option(:username, mandatory: true), async_id) ) data.select! { |l| l['fnid'].to_i > iteration_data.first } unless iteration_data.first.nil? iteration_data[0] = data.last['fnid'].to_i unless data.empty? end return Result::Empty.new if data.empty? skip_ids_persistency&.save Result::ObjectList.new(data) end |
#action_async_show(async_id:) ⇒ Object
async sub-commands: individual handlers
969 970 971 972 973 974 975 976 977 978 979 980 |
# File 'lib/aspera/cli/plugins/node.rb', line 969 def action_async_show(async_id:, **) async_ids = api_node.read('async/list')['sync_ids'] if async_id.eql?(SpecialValues::ALL) resp = api_node.create('async/summary', {'syncs' => async_ids})['sync_summaries'] return Result::Empty.new if resp.empty? return Result::ObjectList.new(resp, fields: %w[snid name local_dir remote_dir]) end Integer(async_id) resp = api_node.create('async/summary', {'syncs' => [async_id]})['sync_summaries'] return Result::Empty.new if resp.empty? Result::SingleObject.new(resp.first) end |
#action_cat(path:) ⇒ Object
696 697 698 699 |
# File 'lib/aspera/cli/plugins/node.rb', line 696 def action_cat(path:, **) http = api_node.read("files/#{URI.encode_www_form_component(path)}/contents", ret: :resp) Result::Text.new(http.body) end |
#action_central_file_list(criteria:) ⇒ Object
central > file > list
1103 1104 1105 1106 1107 1108 1109 1110 1111 |
# File 'lib/aspera/cli/plugins/node.rb', line 1103 def action_central_file_list(criteria:, **) criteria ||= {} validation = central_validation criteria.deep_merge!({'validation' => validation}) unless validation.nil? resp = api_node.create('services/rest/transfers/v1/files', criteria) resp = JSON.parse(resp) if resp.is_a?(String) Log.dump(:resp, resp) Result::ObjectList.new(resp['file_transfer_info_result']['file_transfer_info'], fields: %w[session_uuid file_id status path]) end |
#action_central_file_modify(file:) ⇒ Object
central > file > modify
1114 1115 1116 1117 1118 1119 1120 |
# File 'lib/aspera/cli/plugins/node.rb', line 1114 def action_central_file_modify(file:, **) file ||= {} validation = central_validation file.deep_merge!(validation) unless validation.nil? api_node.update('services/rest/transfers/v1/files', file) Result::Status.new('updated') end |
#action_central_session_list(criteria:) ⇒ Object
central > session > list
1094 1095 1096 1097 1098 1099 1100 |
# File 'lib/aspera/cli/plugins/node.rb', line 1094 def action_central_session_list(criteria:, **) criteria ||= {} validation = central_validation criteria.deep_merge!({'validation' => validation}) unless validation.nil? resp = api_node.create('services/rest/transfers/v1/sessions', criteria) Result::ObjectList.new(resp['session_info_result']['session_info'], fields: %w[session_uuid status transport direction bytes_transferred]) end |
#action_delete(paths:) ⇒ Object
--- Handler methods (Gen3) ---
601 602 603 604 605 606 |
# File 'lib/aspera/cli/plugins/node.rb', line 601 def action_delete(paths:, **) # TODO: add query for recursive paths_to_delete = Array(paths) resp = api_node.create('files/delete', {paths: paths_to_delete.map { |i| {'path' => i.start_with?('/') ? i : "/#{i}"} }}) cli_result_from_paths_response(resp, 'file deleted') end |
#action_download ⇒ Object
683 684 685 686 687 688 689 690 691 692 693 694 |
# File 'lib/aspera/cli/plugins/node.rb', line 683 def action_download(**) # empty transfer spec for authorization request request_transfer_spec = {} request_transfer_spec[:paths] = transfer.ts_source_paths # add fixed parameters if any (for COS) api_node.add_tspec_info(request_transfer_spec) if api_node.respond_to?(:add_tspec_info) Api::Node.add_public_key(request_transfer_spec) setup_payload = {transfer_requests: [{transfer_request: request_transfer_spec}]} transfer_spec = api_node.create('files/download_setup', setup_payload)['transfer_specs'].first['transfer_spec'] Api::Node.add_private_key(transfer_spec) Runner.result_transfer(transfer.start(transfer_spec)) end |
#action_health ⇒ Object
701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 |
# File 'lib/aspera/cli/plugins/node.rb', line 701 def action_health(**) nagios = Nagios.new begin info = api_node.read('info') nagios.add_ok('node api', 'accessible') nagios.check_time_offset(info['current_time'], 'node api') nagios.check_product_version('node api', 'entsrv', info['version']) rescue StandardError => e nagios.add_critical('node api', e.to_s) end begin api_node.call( operation: 'POST', subpath: 'services/soap/Transfer-201210', content_type: Mime::TEXT, body: CENTRAL_SOAP_API_TEST, headers: {'Content-Type' => 'text/xml;charset=UTF-8', 'SOAPAction' => 'FASPSessionNET-200911#GetSessionInfo'}, ret: :resp ).body nagios.add_ok('central', 'accessible by node') rescue StandardError => e nagios.add_critical('central', e.to_s) end Result::ObjectList.new(nagios.status_list) end |
#action_mkdir(paths:) ⇒ Object
627 628 629 630 631 |
# File 'lib/aspera/cli/plugins/node.rb', line 627 def action_mkdir(paths:, **) paths = Array(paths) resp = api_node.create('files/create', {'paths' => paths.map { |i| {type: :directory, path: i} }}) cli_result_from_paths_response(resp, 'folder created') end |
#action_mkfile(path:, contents:) ⇒ Object
638 639 640 641 642 |
# File 'lib/aspera/cli/plugins/node.rb', line 638 def action_mkfile(path:, contents:, **) contents64 = contents.nil? ? '' : Base64.strict_encode64(contents) resp = api_node.create('files/create', {'paths' => [{type: :file, path: path, contents: contents64}]}) cli_result_from_paths_response(resp, 'file created') end |
#action_mklink(target:, link_path:) ⇒ Object
633 634 635 636 |
# File 'lib/aspera/cli/plugins/node.rb', line 633 def action_mklink(target:, link_path:, **) resp = api_node.create('files/create', {'paths' => [{type: :symbolic_link, path: link_path, target: {path: target}}]}) cli_result_from_paths_response(resp, 'link created') end |
#action_rename(folder:, source:, destination:) ⇒ Object
644 645 646 647 648 |
# File 'lib/aspera/cli/plugins/node.rb', line 644 def action_rename(folder:, source:, destination:, **) # TODO: multiple ? resp = api_node.create('files/rename', {'paths' => [{'path' => folder, 'source' => source, 'destination' => destination}]}) cli_result_from_paths_response(resp, 'entry moved') end |
#action_search(path:) ⇒ Object
608 609 610 611 612 613 614 615 616 617 618 619 |
# File 'lib/aspera/cli/plugins/node.rb', line 608 def action_search(path:, **) parameters = {'path' => path} # not a URL query: merged into the POST body of files/search = .get_option(:query) parameters.merge!() unless .nil? resp = api_node.create('files/search', parameters) return Result::Empty.new if resp['items'].empty? fields = resp['items'].first.keys.reject { |i| SEARCH_REMOVE_FIELDS.include?(i) } formatter.display_item_count(resp['item_count'], resp['total_count']) formatter.display_status("params: #{resp['parameters'].keys.map { |k| "#{k}:#{resp['parameters'][k]}" }.join(',')}") Result::ObjectList.new(resp['items'], fields: fields) end |
#action_simulator(parameters: {}) ⇒ Object
1134 1135 1136 1137 1138 1139 1140 1141 1142 |
# File 'lib/aspera/cli/plugins/node.rb', line 1134 def action_simulator(parameters: {}, **) require 'aspera/node_simulator' parameters = parameters.symbolize_keys uri = URI.parse(parameters.delete(:url) { WebServerSimple::DEFAULT_URL }) server = WebServerSimple.new(uri, **parameters.slice(*WebServerSimple::PARAMS)) server.mount(uri.path, NodeSimulatorServlet, parameters.except(*WebServerSimple::PARAMS), NodeSimulator.new) server.start return Result::Status.new('Simulator terminated') end |
#action_space(paths:) ⇒ Object
621 622 623 624 625 |
# File 'lib/aspera/cli/plugins/node.rb', line 621 def action_space(paths:, **) paths = Array(paths) resp = api_node.create('space', {'paths' => paths.map { |i| {path: i} }}) Result::ObjectList.new(resp['paths']) end |
#action_telemetry(parameters: {}) ⇒ Object
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 |
# File 'lib/aspera/cli/plugins/node.rb', line 1144 def action_telemetry(parameters: {}, **) parameters = parameters.symbolize_keys %i[url key].each do |psym| Aspera.assert(parameters.key?(psym), type: Cli::BadArgument) { "Missing parameter: #{psym}" } end require 'socket' parameters[:interval] = 10 unless parameters.key?(:interval) parameters[:hostname] = Socket.gethostname unless parameters.key?(:hostname) interval = parameters[:interval].to_f Aspera.assert(interval >= 0, type: Cli::BadArgument) { 'Interval must be a positive number in seconds, or 0 for single shot' } otel_api = Rest::Client.new( base_url: "#{parameters[:url]}/v1", headers: { # 'Authorization' => "apiToken #{parameters[:key]}", 'x-instana-key' => parameters[:key], 'x-instana-host' => parameters[:hostname] } ) datapoint = { attributes: [ { key: 'server.name', value: { stringValue: 'HSTS1' } } ], asInt: nil, timeUnixNano: nil } # https://opentelemetry.io/docs/specs/otel/metrics/data-model/#gauge metrics = { resourceMetrics: [ { resource: { attributes: [ { key: 'service.name', value: { stringValue: 'IBMAspera' } } ] }, scopeMetrics: [ { metrics: [ { name: 'active.transfers', description: 'Number of active transfers', unit: '1', gauge: { dataPoints: [ datapoint ] } } ] } ] } ] } loop do = Time.now transfers_data = api_node.read_with_paging('ops/transfers', {active_only: true}) datapoint[:asInt] = transfers_data.length datapoint[:timeUnixNano] = .to_i * 1_000_000_000 + .nsec Log.log.info("#{datapoint[:asInt]} active transfers") # https://www.ibm.com/docs/en/instana-observability/current?topic=instana-backend otel_api.create('metrics', metrics) break if interval.eql?(0.0) sleep([0.0, interval - (Time.now - )].max) end end |
#action_transfer_bandwidth_average ⇒ Object
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 |
# File 'lib/aspera/cli/plugins/node.rb', line 1057 def action_transfer_bandwidth_average(**) transfers_data = api_node.read('ops/transfers', query_read_delete(schema: Schema::Registry.query_params(Schema::Registry::NODE, 'ops/transfers'))) bandwidth_period = {} dir_info = %i[avg_kbps sessions].freeze transfers_data.each do |t| next if t['avg_rate_kbps'].zero? bandwidth_period[t['start_time_usec']] = 0 bandwidth_period[t['end_time_usec']] = 0 end result = [] all_dates = bandwidth_period.keys.sort all_dates.each_with_index do |start_date, index| end_date = all_dates[index + 1] break if end_date.nil? period_bandwidth = Transfer::Spec::DIRECTION_ENUM_VALUES.map(&:to_sym).to_h do |dir| [dir, dir_info.to_h { |k2| [k2, 0] }] end transfers_data.each do |t| next if t['avg_rate_kbps'].zero? next if t['start_time_usec'] >= end_date || t['end_time_usec'] <= start_date info = period_bandwidth[t['start_spec']['direction'].to_sym] info[:avg_kbps] += t['avg_rate_kbps'] info[:sessions] += 1 end next if Transfer::Spec::DIRECTION_ENUM_VALUES.map(&:to_sym).all? { |dir| period_bandwidth[dir][:sessions].zero? } result.push({start: Time.at(start_date / 1_000_000), end: Time.at(end_date / 1_000_000)}.merge(period_bandwidth)) end Result::ObjectList.new(result) end |
#action_transfer_list ⇒ Object
transfer sub-commands
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 |
# File 'lib/aspera/cli/plugins/node.rb', line 1024 def action_transfer_list(**) transfer_filter = query_read_delete(default: {}, schema: Schema::Registry.query_params(Schema::Registry::NODE, 'ops/transfers')) iteration_persistency = nil if .get_option(:once_only, mandatory: true) iteration_persistency = PersistencyActionOnce.new( manager: persistency, data: [], id: IdGenerator.from_list('node_transfers', .get_option(:url, mandatory: true), .get_option(:username, mandatory: true)) ) if transfer_filter.delete('reset') iteration_persistency.data.clear iteration_persistency.save return Result::Status.new('Persistency reset') end else Aspera.assert(!transfer_filter.key?('reset'), 'reset only with once_only', type: Cli::BadArgument) end transfers_data = api_node.read_with_paging('ops/transfers', transfer_filter, iteration: iteration_persistency&.data) iteration_persistency&.save Result::ObjectList.new(transfers_data, fields: %w[id status start_spec.direction start_spec.remote_user start_spec.remote_host start_spec.destination_path]) end |
#action_transfer_sessions ⇒ Object
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 |
# File 'lib/aspera/cli/plugins/node.rb', line 1046 def action_transfer_sessions(**) transfers_data = api_node.read('ops/transfers', query_read_delete(schema: Schema::Registry.query_params(Schema::Registry::NODE, 'ops/transfers'))) sessions = transfers_data.flat_map { |t| t['sessions'] } sessions.each do |session| SESSION_TIME_FIELDS.each do |what| session["#{what}_time"] = session["#{what}_time_usec"] ? Time.at(session["#{what}_time_usec"] / 1_000_000.0).utc.iso8601(0) : nil end end Result::ObjectList.new(sessions, fields: %w[id status start_time end_time target_rate_kbps]) end |
#action_upload ⇒ Object
669 670 671 672 673 674 675 676 677 678 679 680 681 |
# File 'lib/aspera/cli/plugins/node.rb', line 669 def action_upload(**) # empty transfer spec for authorization request request_transfer_spec = {} request_transfer_spec[:paths] = [{destination: transfer.destination_folder(Transfer::Spec::DIRECTION_SEND)}] # add fixed parameters if any (for COS) api_node.add_tspec_info(request_transfer_spec) if api_node.respond_to?(:add_tspec_info) Api::Node.add_public_key(request_transfer_spec) setup_payload = {transfer_requests: [{transfer_request: request_transfer_spec}]} transfer_spec = api_node.create('files/upload_setup', setup_payload)['transfer_specs'].first['transfer_spec'] Api::Node.add_private_key(transfer_spec) transfer_spec.delete('paths') Runner.result_transfer(transfer.start(transfer_spec)) end |
#api_node ⇒ Api::Node, Rest::Client
Node API: provided by the host plugin, or built from CLI options on first use.
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/aspera/cli/plugins/node.rb', line 178 def api_node @api_node ||= if OAuth::Factory.bearer_auth?(.get_option(:password, mandatory: true)) # info is provided like node_info of aoc Api::Node.new( base_url: .get_option(:url, mandatory: true), headers: Api::Node.bearer_headers(.get_option(:password, mandatory: true)) ) else # this is normal case Api::Node.new( base_url: .get_option(:url, mandatory: true), auth: { type: :basic, username: .get_option(:username, mandatory: true), password: .get_option(:password, mandatory: true) } ) end end |
#apifid_from_path(top_file_id, path) ⇒ Object
Resolve a NodeFileId from a path argument. Supports %id:<file_id> syntax (returns NodeFileId for that id) or a plain path.
287 288 289 290 291 292 293 294 |
# File 'lib/aspera/cli/plugins/node.rb', line 287 def apifid_from_path(top_file_id, path) if (m = Parser.percent_selector(path)) Aspera.assert_values(m[:field], ['id'], type: BadArgument) { 'file id' } val = m[:value] return Api::NodeFileId.new(api_node, val.nil? || val.empty? ? top_file_id : val) end api_node.resolve_api_fid(top_file_id, path) end |
#async_lookup(field, value) ⇒ Integer
Search /async by name
301 302 303 304 305 306 307 308 |
# File 'lib/aspera/cli/plugins/node.rb', line 301 def async_lookup(field, value) Aspera.assert_values(field, ['name'], type: Cli::BadArgument) { 'search field' } async_ids = api_node.read('async/list')['sync_ids'] summaries = api_node.create('async/summary', {'syncs' => async_ids})['sync_summaries'] selected = summaries.find { |s| s['name'].eql?(value) } raise Cli::BadIdentifier.new('sync', value, field: field) if selected.nil? return selected['snid'] end |
#browse_gen3(path) ⇒ Object
Gen3 API
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/aspera/cli/plugins/node.rb', line 201 def browse_gen3(path) folders_to_process = path folders_to_process = [folders_to_process] # not a URL query: merged into the POST body of files/browse query = .get_option(:query) || {} # special parameter: max number of entries in result max_items = query.delete(Rest::List::MAX_ITEMS) # special parameter: recursive browsing recursive = query.delete('recursive') # special parameter: only return one entry for the path, even if folder only_path = query.delete('self') # allow user to specify a single call, and not recursive single_call = query.key?('skip') # API default is 100, so use 1000 for default query['count'] ||= 1000 Aspera.assert(!(recursive && single_call), type: Cli::BadArgument) { 'options `recursive` and `skip` cannot be used together' } all_items = [] until folders_to_process.empty? path = folders_to_process.shift query['path'] = path offset = 0 total_count = nil loop do # example: send_result={'items'=>[{'file'=>"filename1","permissions"=>[{'name'=>'read'},{'name'=>'write'}]}]} response = api_node.create('files/browse', query) # 'file','symbolic_link' return Result::SingleObject.new(response['self']) if !Node.gen3_entry_folder?(response['self']) || only_path items = response['items'] total_count ||= response['total_count'] all_items.concat(items) if single_call formatter.display_item_count(response['item_count'], total_count) break end folders_to_process.concat(items.select { |i| Node.gen3_entry_folder?(i) }.map { |i| i['path'] }) if recursive if !max_items.nil? && (all_items.count >= max_items) all_items = all_items.slice(0, max_items) if all_items.count > max_items break end break if all_items.count >= total_count offset += items.count query['skip'] = offset Rest::Parameters.instance.spinner_cb.call(all_items.count) end query.delete('skip') end return Result::ObjectList.new(all_items) ensure Rest::Parameters.instance.spinner_cb.call(action: :success) end |
#central_validation ⇒ Object
central: shared helper
1088 1089 1090 1091 |
# File 'lib/aspera/cli/plugins/node.rb', line 1088 def central_validation validator_id = .get_option(:validator) validator_id ? {'validator_id' => validator_id} : nil end |
#gen4_apifid_info(do_root_file_id, path) ⇒ Object
access_keys > do > node_info / bearer_token_node — shared helper builds the result hash
851 852 853 854 855 856 857 858 859 860 861 862 863 864 |
# File 'lib/aspera/cli/plugins/node.rb', line 851 def gen4_apifid_info(do_root_file_id, path) apifid = apifid_from_path(do_root_file_id, path) result = {url: apifid.node_api.base_url, root_id: apifid.file_id} case apifid.node_api.auth_params[:type] when :basic result[:username] = apifid.node_api.auth_params[:username] result[:password] = apifid.node_api.auth_params[:password] when :oauth2 result[:username] = apifid.node_api.params[:headers][Api::Node::HEADER_X_ASPERA_ACCESS_KEY] result[:password] = apifid.node_api.oauth. else Aspera.error_unexpected_value(apifid.node_api.auth_params[:type]) { 'Node API Auth type' } end [apifid, result] end |
#gen4_mk_resolve(top_file_id, path) ⇒ Array(NodeFileId, Hash)
access_keys > do > mkdir / mklink / mkfile — shared helper: resolve parent folder, build payload from query option, optionally check for name collision.
883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 |
# File 'lib/aspera/cli/plugins/node.rb', line 883 def gen4_mk_resolve(top_file_id, path) containing_folder_path, new_item = Api::Node.split_folder(path) apifid = api_node.resolve_api_fid(top_file_id, containing_folder_path, true) # not a URL query: special keys `check` and `target`, rest merged into the POST body query = .get_option(:query) check_exists = true payload = {name: new_item} if query check_exists = !query.delete('check').eql?(false) target = query.delete('target') if target target_apifid = api_node.resolve_api_fid(top_file_id, target, true) payload[:target_id] = target_apifid.file_id end payload.merge!(query.symbolize_keys) end if check_exists folder_content = apifid.node_api.read("files/#{apifid.file_id}/files") link_name = ".#{new_item}.asp-lnk" found = folder_content.find { |i| i['name'].eql?(new_item) || i['name'].eql?(link_name) } Aspera.assert(!found, type: Cli::Error) { "A #{found['type']} already exists with name #{new_item}" } end [apifid, payload] end |
#lookup_access_key_self_id(field, value) ⇒ String
Lookup for access_keys: only supports %id:self selector.
314 315 316 317 |
# File 'lib/aspera/cli/plugins/node.rb', line 314 def lookup_access_key_self_id(field, value, **) Aspera.assert(field.eql?('id') && value.eql?('self'), type: BadArgument) { 'only selector: %id:self' } api_node.read('access_keys/self')['id'] end |
#setup_access_key_do(access_key_id:) ⇒ Hash
access_keys > do - setup: resolve access key and root file id
735 736 737 738 739 740 741 742 743 744 745 746 747 748 |
# File 'lib/aspera/cli/plugins/node.rb', line 735 def setup_access_key_do(access_key_id:, **) @do_root_file_id = .get_option(:root_id) if @do_root_file_id.nil? ak_info = api_node.read("access_keys/#{access_key_id}") ak_secret = context.secret_finder.lookup(url: api_node.base_url, username: ak_info['id']) if !access_key_id.eql?('self') Aspera.assert(ak_secret, type: Cli::MissingArgument) { "Please provide secret for #{ak_info['id']} using option: secret or by setting a preset for #{ak_info['id']}@#{api_node.base_url}." } api_node.auth_params[:username] = ak_info['id'] api_node.auth_params[:password] = ak_secret end @do_root_file_id = ak_info['root_file_id'] end {do_root_file_id: @do_root_file_id} end |
#setup_access_key_do_permission(do_root_file_id:, path:) ⇒ Hash
access_keys > do > permission - setup: resolve apifid from the path argument of the node do_root_file_id: comes from ctx (setup_access_key_do, or seed of a mount)
753 754 755 |
# File 'lib/aspera/cli/plugins/node.rb', line 753 def (do_root_file_id:, path:, **) {apifid: apifid_from_path(do_root_file_id, path)} end |
#setup_watch_folder ⇒ Object
watch_folder setup: inject required API header (avoids "Unable to convert 2016_09_14 configuration")
728 729 730 731 |
# File 'lib/aspera/cli/plugins/node.rb', line 728 def setup_watch_folder(**) api_node.headers['X-aspera-WF-version'] = '2017_10_23' {} end |
#ssync_lookup(field, value) ⇒ Integer
Search /asyncs by name
324 325 326 327 328 329 330 331 332 |
# File 'lib/aspera/cli/plugins/node.rb', line 324 def ssync_lookup(field, value) Aspera.assert_values(field, ['name'], type: Cli::BadArgument) { 'search field' } api_node.read('asyncs')['ids'].each do |id| sync_info = api_node.read("asyncs/#{id}")['configuration'] # name is unique, so we can return return id if sync_info[field].eql?(value) end raise Cli::BadIdentifier.new('ssync', value, field: field) end |
#sync_gen3_block ⇒ Object
Obtains a transfer spec via the Node API for the given direction/folders.
651 652 653 654 655 656 657 658 659 660 661 662 663 |
# File 'lib/aspera/cli/plugins/node.rb', line 651 def sync_gen3_block lambda do |direction, local_path, remote_path| request_transfer_spec = sync_spec_request(direction, local_path, remote_path) api_node.add_tspec_info(request_transfer_spec) if api_node.respond_to?(:add_tspec_info) transfer_spec = api_node.create( 'files/sync_setup', {transfer_requests: [{transfer_request: request_transfer_spec}]} )['transfer_specs'].first['transfer_spec'] transfer_spec.delete_if { |_k, v| v.nil? } Log.dump(:ts, transfer_spec) transfer_spec end end |
#sync_gen4_block(do_root_file_id) ⇒ Object
Shared Gen4 sync block: obtains a transfer spec via the Gen4 API for the given direction/remote_path.
818 819 820 821 822 823 824 |
# File 'lib/aspera/cli/plugins/node.rb', line 818 def sync_gen4_block(do_root_file_id) lambda do |direction, _local_path, remote_path| ts_direction = direction.eql?(:pull) ? Transfer::Spec::DIRECTION_RECEIVE : Transfer::Spec::DIRECTION_SEND apifid = api_node.resolve_api_fid(do_root_file_id, remote_path) apifid.node_api.transfer_spec_gen4(apifid.file_id, ts_direction) end end |
#sync_spec_request(sync_direction, local_path, remote_path) ⇒ Object
Create async transfer spec request from direction and folders
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/aspera/cli/plugins/node.rb', line 256 def sync_spec_request(sync_direction, local_path, remote_path) case sync_direction when :push then { type: :sync_upload, paths: [{ source: local_path, destination: remote_path }] } when :pull then { type: :sync_download, paths: [{ source: remote_path, destination: local_path }] } when :bidi then { type: :sync, paths: [{ source: local_path, destination: remote_path }] } else Aspera.error_unexpected_value(sync_direction) end end |
#v3_node_plugin(do_root_file_id:) ⇒ Node
access_keys > do > v3 - mount target: Node plugin on the node hosting the root file
846 847 848 |
# File 'lib/aspera/cli/plugins/node.rb', line 846 def v3_node_plugin(do_root_file_id:, **) Node.new(context: context, api: api_node.resolve_api_fid(do_root_file_id, '').node_api) end |
#wizard(wizard, app_url) ⇒ Hash
Returns :preset_value, :test_args.
86 87 88 89 90 91 92 93 94 95 |
# File 'lib/aspera/cli/plugins/node.rb', line 86 def wizard(wizard, app_url) return { preset_value: { url: app_url, username: .get_option(:username, mandatory: true), password: .get_option(:password, mandatory: true) }, test_args: 'info' } end |