Class: Aspera::Api::CosNode

Inherits:
Node show all
Defined in:
lib/aspera/api/cos_node.rb

Constant Summary collapse

IBM_CLOUD_TOKEN_URL =
'https://iam.cloud.ibm.com/identity'
TOKEN_FIELD =
'delegated_refresh_token'

Constants inherited from Node

Node::ACCESS_LEVELS, Node::HEADER_X_ASPERA_ACCESS_KEY, Node::HEADER_X_TOTAL_COUNT, Node::PATH_SEPARATOR, Node::SCOPE_ADMIN, Node::SCOPE_USER

Constants inherited from Rest

Rest::ENTITY_NOT_FOUND, Rest::JSON_DECODE

Instance Attribute Summary

Attributes inherited from Node

#app_info

Attributes inherited from Rest

#auth_params, #base_url

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Node

#add_tspec_info, bearer_headers, bearer_token, decode_bearer_token, decode_scope, #entry_has_link_information, file_matcher, file_matcher_from_argument, #find_files, #node_id_to_node, #process_folder_tree, #refreshed_transfer_token, #resolve_api_fid, token_scope, #transfer_spec_gen4, #transport_params

Methods inherited from Rest

array_params, array_params?, basic_token, build_uri, #call, #cancel, #create, decode_query, #delete, io_http_session, #lookup_by_name, #oauth, #params, parse_header, #read, remote_certificate_chain, set_parameters, start_http_session, #update, user_agent

Constructor Details

#initialize(instance_id:, api_key:, endpoint:, bucket:, auth_url: IBM_CLOUD_TOKEN_URL) ⇒ CosNode

Returns a new instance of CosNode.



34
35
36
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
67
68
69
70
71
72
73
74
75
# File 'lib/aspera/api/cos_node.rb', line 34

def initialize(instance_id:, api_key:, endpoint:, bucket:, auth_url: IBM_CLOUD_TOKEN_URL)
  Aspera.assert_type(instance_id, String){'resource instance id (crn)'}
  Aspera.assert_type(endpoint, String){'endpoint'}
  endpoint = "https://#{endpoint}" unless endpoint.start_with?('http')
  @auth_url = auth_url
  @api_key = api_key
  s3_api = Aspera::Rest.new(
    base_url:       endpoint,
    not_auth_codes: %w[401 403], # error codes when not authorized
    headers:        {'ibm-service-instance-id' => instance_id},
    auth:           {
      type:          :oauth2,
      grant_method:  :generic,
      base_url:      @auth_url,
      grant_type:    'urn:ibm:params:oauth:grant-type:apikey',
      response_type: 'cloud_iam',
      apikey:        @api_key
    })
  # read FASP connection information for bucket
  xml_result_text = s3_api.call(
    operation: 'GET',
    subpath:   bucket,
    headers:   {'Accept' => 'application/xml'},
    query:     {'faspConnectionInfo' => nil}
  )[:http].body
  ats_info = XmlSimple.xml_in(xml_result_text, {'ForceArray' => false})
  Aspera::Log.dump('ats_info', ats_info)
  @storage_credentials = {
    'type'  => 'token',
    'token' => {TOKEN_FIELD => nil}
  }
  super(
    base_url: ats_info['ATSEndpoint'],
    auth:     {
      type:     :basic,
      username: ats_info['AccessKey']['Id'],
      password: ats_info['AccessKey']['Secret']},
    add_tspec: {'tags'=>{Transfer::Spec::TAG_RESERVED=>{'node'=>{'storage_credentials'=>@storage_credentials}}}}
    )
  # update storage_credentials AND Rest params
  generate_token
end

Class Method Details

.parameters_from_svc_credentials(service_credentials, bucket_region) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/aspera/api/cos_node.rb', line 14

def parameters_from_svc_credentials(service_credentials, bucket_region)
  # check necessary contents
  Aspera.assert_type(service_credentials, Hash){'service_credentials'}
  Aspera::Log.dump('service_credentials', service_credentials)
  %w[apikey resource_instance_id endpoints].each do |field|
    Aspera.assert(service_credentials.key?(field)){"service_credentials must have a field: #{field}"}
  end
  # read endpoints from service provided in service credentials
  endpoints = Aspera::Rest.new(base_url: service_credentials['endpoints']).read('')[:data]
  Aspera::Log.dump('endpoints', endpoints)
  endpoint = endpoints.dig('service-endpoints', 'regional', bucket_region, 'public', bucket_region)
  raise "no such region: #{bucket_region}" if endpoint.nil?
  return {
    instance_id: service_credentials['resource_instance_id'],
    api_key:     service_credentials['apikey'],
    endpoint:    endpoint
  }
end

Instance Method Details

#generate_tokenObject

potentially call this if delegated token is expired



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/aspera/api/cos_node.rb', line 78

def generate_token
  # OAuth API to get delegated token
  delegated_oauth = OAuth::Factory.instance.create(
    base_url:     @auth_url,
    grant_method: :generic,
    token_field:  TOKEN_FIELD,
    grant_type:          'urn:ibm:params:oauth:grant-type:apikey',
    response_type:       'delegated_refresh_token',
    apikey:              @api_key,
    receiver_client_ids: 'aspera_ats'
  )
  # get delegated token to be placed in rest call header and in transfer tags
  @storage_credentials['token'][TOKEN_FIELD] = OAuth::Factory.bearer_extract(delegated_oauth.token)
  @headers['X-Aspera-Storage-Credentials'] = JSON.generate(@storage_credentials)
end