class Fog::HP::BlockStorageV2::Real

Attributes

credentials[R]

Public Class Methods

new(options={}) click to toggle source
# File lib/fog/hp/block_storage_v2.rb, line 91
def initialize(options={})
  @hp_access_key = options[:hp_access_key]
  @hp_secret_key = options[:hp_secret_key]
  @hp_auth_uri   = options[:hp_auth_uri]
  @connection_options = options[:connection_options] || {}
  ### Set an option to use the style of authentication desired; :v1 or :v2 (default)
  auth_version = options[:hp_auth_version] || :v2
  ### Pass the service name for block storage to the authentication call
  options[:hp_service_type] ||= "Block Storage"
  @hp_tenant_id = options[:hp_tenant_id]
  @hp_avl_zone  = options[:hp_avl_zone]

  ### Make the authentication call
  if (auth_version == :v2)
    # Call the control services authentication
    credentials = Fog::HP.authenticate_v2(options, @connection_options)
    # the CS service catalog returns the block storage endpoint
    @hp_block_uri = credentials[:endpoint_url]
    @credentials = credentials
  else
    # Call the legacy v1.0/v1.1 authentication
    credentials = Fog::HP.authenticate_v1(options, @connection_options)
    # the user sends in the block storage endpoint
    @hp_block_uri = options[:hp_auth_uri]
  end

  @auth_token = credentials[:auth_token]
  @persistent = options[:persistent] || false

  uri = URI.parse(@hp_block_uri)
  @host   = uri.host
  @path   = uri.path
  @port   = uri.port
  @scheme = uri.scheme

  @connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
end

Public Instance Methods

create_snapshot(volume_id, options={}) click to toggle source

Create a new block storage snapshot The snapshot is created in the same availability_zone as the specified volume

Parameters

  • 'volume_id'<~String> - UUId of the volume to create the snapshot from

  • options<~Hash>:

    • 'display_name'<~String> - Name of the snapshot

    • 'display_description'<~String> - Description of the snapshot

    • 'force'<~Boolean> - true or false, defaults to false. It allows online snapshots (i.e. when volume is attached)

Returns

  • response<~Excon::Response>:

    • body<~Hash>:

      • snapshot<~Hash>:

        • 'id'<~String>: - UUId for the snapshot

        • 'display_name'<~String>: - Name of the snapshot

        • 'display_description'<~String>: - Description of the snapshot

        • 'size'<~Integer>: - Size in GB for the snapshot

        • 'status'<~String>: - Status of the snapshot i.e. “available”

        • 'volume_id'<~String>: - UUId of the volume from which the snapshot was created

        • 'created_at'<~String>: - Timestamp in UTC when volume was created

        • metadata<~Hash>: Hash of metadata for the snapshot

# File lib/fog/hp/requests/block_storage_v2/create_snapshot.rb, line 27
def create_snapshot(volume_id, options={})
  data = {
    'snapshot' => {
      'volume_id'  => volume_id
    }
  }

  l_options = ['display_name', 'display_description', 'force']
  l_options.select{|o| options[o]}.each do |key|
    data['snapshot'][key] = options[key]
  end

  request(
    :body     => Fog::JSON.encode(data),
    :expects  => 200,
    :method   => 'POST',
    :path     => 'snapshots'
  )
end
create_volume(options={}) click to toggle source

Create a new block storage volume

Parameters

  • options<~Hash>:

    • 'display_name'<~String> - Name of the volume

    • 'display_description'<~String> - Description of the volume

    • 'size'<~Integer> - Size of the volume (in GBs). Size is optional only if 'snapshot_id' is specified.

    • 'snapshot_id'<~String> - UUId of the volume snapshot to create the volume from. The snapshot_id, imageRef and the source_volid parameters are mutually exclusive, and only one should be specified in the request.

    • 'imageRef'<~String> - UUId of the image to create the volume from. This creates a bootable volume. The snapshot_id, imageRef and the source_volid parameters are mutually exclusive, and only one should be specified in the request.

    • 'source_volid'<~String> - UUId of an 'available' volume to create the volume from. The request is invalid if the volume is not available. The snapshot_id, imageRef and the source_volid parameters are mutually exclusive, and only one should be specified in the request.

    • 'availability_zone'<~String> - Availability zone where the volume should be created. Defaults to 'az1'.

    • 'volume_type'<~String> - Type of the volume

    • 'metadata'<~Hash> - Up to 5 key value pairs containing 255 bytes of info

Returns

  • response<~Excon::Response>:

    • body<~Hash>:

      • volume<~Hash>:

        • 'id'<~String> - UUId for the volume

        • 'display_name'<~String> - Name of the volume

        • 'display_description'<~String> - Description of the volume

        • 'size'<~Integer> - Size in GB for the volume

        • 'status'<~String> - Status of the volume i.e. “creating”

        • 'volume_type'<~String> - Type of the volume

        • 'snapshot_id'<~String> - UUId of the snapshot, the volume was created from.

        • 'source_volid'<~String> - UUId of a volume, the volume was created from.

        • 'created_at'<~String> - Timestamp in UTC when volume was created

        • 'availability_zone'<~String> - Availability zone i.e. “az1”

        • attachments<~Array>: Array of hashes of attachments

        • metadata<~Hash>: Hash of metadata for the volume

# File lib/fog/hp/requests/block_storage_v2/create_volume.rb, line 35
def create_volume(options={})
  data = {
    'volume' => {}
  }

  l_options = ['display_name', 'display_description', 'size',
               'snapshot_id', 'imageRef', 'source_volid',
               'availability_zone', 'volume_type', 'metadata']
  l_options.select{|o| options[o]}.each do |key|
    data['volume'][key] = options[key]
  end

  request(
    :body     => Fog::JSON.encode(data),
    :expects  => 200,
    :method   => 'POST',
    :path     => 'volumes'
  )
end
create_volume_backup(volume_id, options={}) click to toggle source

Create a new block storage volume backup

Parameters

  • 'volume_id'<~String> - UUId for the volume to backup

  • options<~Hash>:

    • 'name'<~String> - Name of the volume backup

    • 'description'<~String> - Description of the volume backup

    • 'container'<~String> - The object storage container where the backup will be stored. Defaults to 'volumebackups', if not specified at creating time.

Returns

  • response<~Excon::Response>:

    • body<~Hash>:

      • backup<~Hash>:

        • 'id'<~String> - UUId for the volume backup

        • 'name'<~String> - Name of the volume backup

        • 'links'<~Array> - array of volume backup links

# File lib/fog/hp/requests/block_storage_v2/create_volume_backup.rb, line 21
def create_volume_backup(volume_id, options={})
  data = {
    'backup' => {
      'volume_id' => volume_id
    }
  }

  l_options = ['name', 'description', 'container']
  l_options.select{|o| options[o]}.each do |key|
    data['backup'][key] = options[key]
  end

  request(
    :body     => Fog::JSON.encode(data),
    :expects  => 202,
    :method   => 'POST',
    :path     => 'backups'
  )
end
delete_snapshot(snapshot_id) click to toggle source

Delete an existing block storage snapshot

Parameters

  • 'snapshot_id'<~String> - UUId of the snapshot to delete

# File lib/fog/hp/requests/block_storage_v2/delete_snapshot.rb, line 10
def delete_snapshot(snapshot_id)
  response = request(
    :expects  => 202,
    :method   => 'DELETE',
    :path     => "snapshots/#{snapshot_id}"
  )
  response
end
delete_volume(volume_id) click to toggle source

Delete an existing block storage volume

Parameters

  • 'volume_id'<~String> - UUId of the volume to delete

# File lib/fog/hp/requests/block_storage_v2/delete_volume.rb, line 10
def delete_volume(volume_id)
  response = request(
    :expects  => 202,
    :method   => 'DELETE',
    :path     => "volumes/#{volume_id}"
  )
  response
end
delete_volume_backup(backup_id) click to toggle source

Delete an existing block storage volume backup

Parameters

  • 'backup_id'<~String> - UUId of the volume backup to delete

# File lib/fog/hp/requests/block_storage_v2/delete_volume_backup.rb, line 10
def delete_volume_backup(backup_id)
  response = request(
    :expects  => 202,
    :method   => 'DELETE',
    :path     => "backups/#{backup_id}"
  )
  response
end
get_snapshot_details(snapshot_id) click to toggle source

Get details for existing block storage snapshot

Parameters

  • 'snapshot_id'<~String> - UUId of the snapshot to get

Returns

  • response<~Excon::Response>:

    • body<~Hash>:

      • snapshot<~Hash>:

        • 'id'<~String>: - UUId for the snapshot

        • 'display_name'<~String>: - Name of the snapshot

        • 'display_description'<~String>: - Description of the snapshot

        • 'size'<~Integer>: - Size in GB for the snapshot

        • 'status'<~String>: - Status of the snapshot i.e. “available”

        • 'volume_id'<~String>: - UUId of the volume from which the snapshot was created

        • 'created_at'<~String>: - Timestamp in UTC when volume was created

        • metadata<~Hash>: Hash of metadata for the snapshot

# File lib/fog/hp/requests/block_storage_v2/get_snapshot_details.rb, line 22
def get_snapshot_details(snapshot_id)
  response = request(
    :expects  => 200,
    :method   => 'GET',
    :path     => "snapshots/#{snapshot_id}"
  )
  response
end
get_volume_backup_details(backup_id) click to toggle source

Get details for existing block storage volume backup

Parameters

  • 'backup_id'<~String> - UUId of the volume backup to get

Returns

  • response<~Excon::Response>:

    • body<~Hash>:

      • backup<~Hash>:

        • 'id'<~String> - UUId for the volume backup

        • 'name'<~String> - Name of the volume backup

        • 'description'<~String> - Description of the volume backup

        • 'container'<~String> - The object storage container where the backup is stored. Defaults to 'volumebackups' if not specified at creating time.

        • 'status'<~String> - Status of the volume backup i.e. “available”

        • 'fail_reason'<~String> - Reason for failure of the volume backup

        • 'object_count'<~Integer> - Number of backups for a volume

        • 'size'<~Integer> - Size of the volume in the backup

        • 'volume_id'<~String> - UUId for the volume in the backup

        • 'created_at'<~String> - Timestamp in UTC when volume backup was created

        • 'availability_zone'<~String> - Availability zone of the backup volume. The backup is created in the same availability zone as the volume.

        • 'links'<~Array> - array of volume backup links

# File lib/fog/hp/requests/block_storage_v2/get_volume_backup_details.rb, line 26
def get_volume_backup_details(backup_id)
  response = request(
    :expects  => 200,
    :method   => 'GET',
    :path     => "backups/#{backup_id}"
  )
  response
end
get_volume_details(volume_id) click to toggle source

Get details for existing block storage volume

Parameters

  • 'volume_id'<~String> - UUId of the volume to get

Returns

  • response<~Excon::Response>:

    • body<~Hash>:

      • volume<~Hash>:

        • 'id'<~String> - UUId for the volume

        • 'display_name'<~String> - Name of the volume

        • 'display_description'<~String> - Description of the volume

        • 'size'<~Integer> - Size in GB for the volume

        • 'status'<~String> - Status of the volume i.e. “creating”

        • 'volume_type'<~String> - Type of the volume

        • 'snapshot_id'<~String> - UUId of the snapshot, the volume was created from.

        • 'source_volid'<~String> - UUId of a volume, the volume was created from.

        • 'created_at'<~String> - Timestamp in UTC when volume was created

        • 'availability_zone'<~String> - Availability zone i.e. “az1”

        • attachments<~Array>: Array of hashes of attachments

        • metadata<~Hash>: Hash of metadata for the volume

# File lib/fog/hp/requests/block_storage_v2/get_volume_details.rb, line 26
def get_volume_details(volume_id)
  response = request(
    :expects  => 200,
    :method   => 'GET',
    :path     => "volumes/#{volume_id}"
  )
  response
end
list_snapshots(options={}) click to toggle source

List existing block storage snapshots

Parameters

  • options<~Hash>: filter options

    • 'display_name'<~String> - Name of the snapshot

    • 'marker'<~String> - The ID of the last item in the previous list

    • 'limit'<~Integer> - Sets the page size

    • 'changes-since'<~DateTime> - Filters by the changes-since time. The list contains servers that have been deleted since the changes-since time.

Returns

  • response<~Excon::Response>:

    • body<~Array>:

      • snapshots<~Hash>:

        • 'id'<~String>: - UUId for the snapshot

        • 'display_name'<~String>: - Name of the snapshot

        • 'display_description'<~String>: - Description of the snapshot

        • 'size'<~Integer>: - Size in GB for the snapshot

        • 'status'<~String>: - Status of the snapshot i.e. 'available'

        • 'volume_id'<~String>: - UUId of the volume from which the snapshot was created

        • 'created_at'<~String>: - Timestamp in UTC when volume was created

        • metadata<~Hash>: Hash of metadata for the snapshot

# File lib/fog/hp/requests/block_storage_v2/list_snapshots.rb, line 26
def list_snapshots(options={})
  response = request(
    :expects  => 200,
    :method   => 'GET',
    :path     => 'snapshots',
    :query    => options
  )
  response
end
list_snapshots_detail(options={}) click to toggle source

List existing block storage snapshots with details

Parameters

  • options<~Hash>: filter options

    • 'display_name'<~String> - Name of the snapshot

    • 'marker'<~String> - The ID of the last item in the previous list

    • 'limit'<~Integer> - Sets the page size

    • 'changes-since'<~DateTime> - Filters by the changes-since time. The list contains servers that have been deleted since the changes-since time.

Returns

  • response<~Excon::Response>:

    • body<~Array>:

      • snapshots<~Hash>:

        • 'id'<~String>: - UUId for the snapshot

        • 'display_name'<~String>: - Name of the snapshot

        • 'display_description'<~String>: - Description of the snapshot

        • 'size'<~Integer>: - Size in GB for the snapshot

        • 'status'<~String>: - Status of the snapshot i.e. “available”

        • 'volume_id'<~String>: - UUId of the volume from which the snapshot was created

        • 'created_at'<~String>: - Timestamp in UTC when volume was created

        • metadata<~Hash>: Hash of metadata for the snapshot

# File lib/fog/hp/requests/block_storage_v2/list_snapshots_detail.rb, line 26
def list_snapshots_detail(options={})
  response = request(
    :expects  => 200,
    :method   => 'GET',
    :path     => 'snapshots/detail',
    :query    => options
  )
  response
end
list_volume_backups(options = {}) click to toggle source

List existing block storage volume backups

Parameters

  • options<~Hash>: filter options

    • 'name'<~String> - Name of the volume

    • 'marker'<~String> - The ID of the last item in the previous list

    • 'limit'<~Integer> - Sets the page size

    • 'changes-since'<~DateTime> - Filters by the changes-since time. The list contains servers that have been deleted since the changes-since time.

Returns

  • response<~Excon::Response>:

    • body<~Array>:

      • backups<~Hash>:

        • 'id'<~String> - UUId for the volume backup

        • 'name'<~String> - Name of the volume backup

        • 'links'<~Array> - array of volume backup links

# File lib/fog/hp/requests/block_storage_v2/list_volume_backups.rb, line 21
def list_volume_backups(options = {})
  response = request(
    :expects  => 200,
    :method   => 'GET',
    :path     => 'backups',
    :query    => options
  )
  response
end
list_volume_backups_detail(options = {}) click to toggle source

List details about existing block storage volume backups

Parameters

  • options<~Hash>: filter options

    • 'name'<~String> - Name of the volume

    • 'marker'<~String> - The ID of the last item in the previous list

    • 'limit'<~Integer> - Sets the page size

    • 'changes-since'<~DateTime> - Filters by the changes-since time. The list contains servers that have been deleted since the changes-since time.

Returns

  • response<~Excon::Response>:

    • body<~Array>:

      • backups<~Hash>:

        • 'id'<~String> - UUId for the volume backup

        • 'name'<~String> - Name of the volume backup

        • 'description'<~String> - Description of the volume backup

        • 'container'<~String> - The object storage container where the backup is stored. Defaults to 'volumebackups' if not specified at creating time.

        • 'status'<~String> - Status of the volume backup i.e. “available”

        • 'fail_reason'<~String> - Reason for failure of the volume backup

        • 'object_count'<~Integer> - Number of backups for a volume

        • 'size'<~Integer> - Size of the volume in the backup

        • 'volume_id'<~String> - UUId for the volume in the backup

        • 'created_at'<~String> - Timestamp in UTC when volume backup was created

        • 'availability_zone'<~String> - Availability zone of the backup volume. The backup is created in the same availability zone as the volume.

        • 'links'<~Array> - array of volume backup links

# File lib/fog/hp/requests/block_storage_v2/list_volume_backups_detail.rb, line 30
def list_volume_backups_detail(options = {})
  response = request(
    :expects  => 200,
    :method   => 'GET',
    :path     => 'backups/detail',
    :query    => options
  )
  response
end
list_volumes(options = {}) click to toggle source

List existing block storage volumes

Parameters

  • options<~Hash>: filter options

    • 'display_name'<~String> - Name of the volume

    • 'marker'<~String> - The ID of the last item in the previous list

    • 'limit'<~Integer> - Sets the page size

    • 'changes-since'<~DateTime> - Filters by the changes-since time. The list contains servers that have been deleted since the changes-since time.

Returns

  • response<~Excon::Response>:

    • body<~Array>:

      • volumes<~Hash>:

        • 'id'<~String> - UUId for the volume

        • 'display_name'<~String> - Name of the volume

        • 'display_description'<~String> - Description of the volume

        • 'size'<~Integer> - Size in GB for the volume

        • 'status'<~String> - Status of the volume i.e. “creating”

        • 'volume_type'<~String> - Type of the volume

        • 'snapshot_id'<~String> - UUId of the snapshot, the volume was created from.

        • 'source_volid'<~String> - UUId of a volume, the volume was created from.

        • 'created_at'<~String> - Timestamp in UTC when volume was created

        • 'availability_zone'<~String> - Availability zone i.e. “az1”

        • attachments<~Array>: Array of hashes of attachments

        • metadata<~Hash>: Hash of metadata for the volume

# File lib/fog/hp/requests/block_storage_v2/list_volumes.rb, line 30
def list_volumes(options = {})
  response = request(
    :expects  => 200,
    :method   => 'GET',
    :path     => 'volumes',
    :query    => options
  )
  response
end
list_volumes_detail(options = {}) click to toggle source

List details about existing block storage volumes

Parameters

  • options<~Hash>: filter options

    • 'display_name'<~String> - Name of the volume

    • 'marker'<~String> - The ID of the last item in the previous list

    • 'limit'<~Integer> - Sets the page size

    • 'changes-since'<~DateTime> - Filters by the changes-since time. The list contains servers that have been deleted since the changes-since time.

Returns

  • response<~Excon::Response>:

    • body<~Array>:

      • volumes<~Hash>:

        • 'id'<~String> - UUId for the volume

        • 'display_name'<~String> - Name of the volume

        • 'display_description'<~String> - Description of the volume

        • 'size'<~Integer> - Size in GB for the volume

        • 'status'<~String> - Status of the volume i.e. “creating”

        • 'volume_type'<~String> - Type of the volume

        • 'snapshot_id'<~String> - UUId of the snapshot, the volume was created from.

        • 'source_volid'<~String> - UUId of a volume, the volume was created from.

        • 'created_at'<~String> - Timestamp in UTC when volume was created

        • 'availability_zone'<~String> - Availability zone i.e. “az1”

        • attachments<~Array>: Array of hashes of attachments

        • metadata<~Hash>: Hash of metadata for the volume

        • volume_image_metadata<~Hash>: Hash of image metadata for the volume, only if the volume was created from an image.

# File lib/fog/hp/requests/block_storage_v2/list_volumes_detail.rb, line 31
def list_volumes_detail(options = {})
  response = request(
    :expects  => 200,
    :method   => 'GET',
    :path     => 'volumes/detail',
    :query    => options
  )
  response
end
reload() click to toggle source
# File lib/fog/hp/block_storage_v2.rb, line 129
def reload
  @connection.reset
end
request(params, parse_json = true, &block) click to toggle source
# File lib/fog/hp/block_storage_v2.rb, line 133
def request(params, parse_json = true, &block)
  begin
    response = @connection.request(params.merge!({
      :headers  => {
        'Content-Type' => 'application/json',
        'Accept'       => 'application/json',
        'X-Auth-Token' => @auth_token
      }.merge!(params[:headers] || {}),
      :path     => "#{@path}/#{params[:path]}"
    }), &block)
  rescue Excon::Errors::HTTPStatusError => error
    raise case error
    when Excon::Errors::NotFound
      Fog::HP::BlockStorageV2::NotFound.slurp(error)
    else
      error
    end
  end
  if !response.body.empty? && parse_json && response.headers['Content-Type'] =~ %r{application/json}
    response.body = Fog::JSON.decode(response.body)
  end
  response
end
restore_volume_backup(backup_id, options={}) click to toggle source

Restore an existing block storage volume backup to an existing or new volume

If a volume is specified, that volume will be overwritten with the backup data from the backup. If no volume is specified, a new volume will be created and used for the restore operation.

Parameters

  • 'backup_id'<~String> - UUId of the volume backup to delete

  • options<~Hash>:

    • 'volume_id'<~String> - UUId of the volume that will be overwritten by the backup data

# File lib/fog/hp/requests/block_storage_v2/restore_volume_backup.rb, line 15
def restore_volume_backup(backup_id, options={})
  data = {
    'restore' => {
      'backup_id' => backup_id
    }
  }

  l_options = ['volume_id']
  l_options.select{|o| options[o]}.each do |key|
    data['restore'][key] = options[key]
  end

  request(
    :body     => Fog::JSON.encode(data),
    :expects  => 202,
    :method   => 'POST',
    :path     => "backups/#{backup_id}/restore"
  )
end
update_snapshot(snapshot_id, options={}) click to toggle source

Update an existing block storage snapshot

Parameters

  • 'snapshot_id'<~String> - UUId of the snapshot to update

  • options<~Hash>:

    • 'display_name'<~String> - Name of the snapshot

    • 'display_description'<~String> - Description of the snapshot

Returns

  • response<~Excon::Response>:

    • body<~Hash>:

      • snapshot<~Hash>:

        • 'id'<~String>: - UUId for the snapshot

        • 'display_name'<~String>: - Name of the snapshot

        • 'display_description'<~String>: - Description of the snapshot

        • 'size'<~Integer>: - Size in GB for the snapshot

        • 'status'<~String>: - Status of the snapshot i.e. “available”

        • 'volume_id'<~String>: - UUId of the volume from which the snapshot was created

        • 'created_at'<~String>: - Timestamp in UTC when volume was created

        • metadata<~Hash>: Hash of metadata for the snapshot

# File lib/fog/hp/requests/block_storage_v2/update_snapshot.rb, line 25
def update_snapshot(snapshot_id, options={})
  data = {
    'snapshot' => {}
  }

  l_options = ['display_name', 'display_description', 'metadata']
  l_options.select{|o| options[o]}.each do |key|
    data['snapshot'][key] = options[key]
  end

  request(
    :body     => Fog::JSON.encode(data),
    :expects  => 200,
    :method   => 'PUT',
    :path     => "snapshots/#{snapshot_id}"
  )
end
update_volume(volume_id, options={}) click to toggle source

Update an existing block storage volume

Parameters

  • 'volume_id'<~String> - UUId of the volume to update

  • options<~Hash>:

    • 'display_name'<~String> - Name of the volume

    • 'display_description'<~String> - Description of the volume

    • 'metadata'<~Hash> - Up to 5 key value pairs containing 255 bytes of info

Returns

  • response<~Excon::Response>:

    • body<~Hash>:

      • volume<~Hash>:

        • 'id'<~String> - UUId for the volume

        • 'display_name'<~String> - Name of the volume

        • 'display_description'<~String> - Description of the volume

        • 'size'<~Integer> - Size in GB for the volume

        • 'status'<~String> - Status of the volume i.e. “creating”

        • 'volume_type'<~String> - Type of the volume

        • 'snapshot_id'<~String> - UUId of the snapshot, the volume was created from.

        • 'source_volid'<~String> - UUId of a volume, the volume was created from.

        • 'created_at'<~String> - Timestamp in UTC when volume was created

        • 'availability_zone'<~String> - Availability zone i.e. “az1”

        • attachments<~Array>: Array of hashes of attachments

        • metadata<~Hash>: Hash of metadata for the volume

# File lib/fog/hp/requests/block_storage_v2/update_volume.rb, line 30
def update_volume(volume_id, options={})
  data = {
    'volume' => {}
  }

  l_options = ['display_name', 'display_description', 'metadata']
  l_options.select{|o| options[o]}.each do |key|
    data['volume'][key] = options[key]
  end

  request(
    :body     => Fog::JSON.encode(data),
    :expects  => 200,
    :method   => 'PUT',
    :path     => "volumes/#{volume_id}"
  )
end