def initialize_connection(self, context, volume_id, connector):
    "Prepare volume for connection from host represented by connector.\n\n        This method calls the driver initialize_connection and returns\n        it to the caller.  The connector parameter is a dictionary with\n        information about the host that will connect to the volume in the\n        following format::\n\n            {\n                'ip': ip,\n                'initiator': initiator,\n            }\n\n        ip: the ip address of the connecting machine\n\n        initiator: the iscsi initiator name of the connecting machine.\n        This can be None if the connecting machine does not support iscsi\n        connections.\n\n        driver is responsible for doing any necessary security setup and\n        returning a connection_info dictionary in the following format::\n\n            {\n                'driver_volume_type': driver_volume_type,\n                'data': data,\n            }\n\n        driver_volume_type: a string to identify the type of volume.  This\n                           can be used by the calling code to determine the\n                           strategy for connecting to the volume. This could\n                           be 'iscsi', 'rbd', 'sheepdog', etc.\n\n        data: this is the data that the calling code will use to connect\n              to the volume. Keep in mind that this will be serialized to\n              json in various places, so it should not contain any non-json\n              data types.\n        "
    utils.require_driver_initialized(self.driver)
    volume = self.db.volume_get(context, volume_id)
    model_update = None
    try:
        self.driver.validate_connector(connector)
    except exception.InvalidConnectorException as err:
        raise exception.InvalidInput(reason=six.text_type(err))
    except Exception as err:
        err_msg = (_('Validate volume connection failed (error: %(err)s).') % {'err': six.text_type(err)})
        LOG.error(err_msg, resource=volume)
        raise exception.VolumeBackendAPIException(data=err_msg)
    try:
        model_update = self.driver.create_export(context.elevated(), volume, connector)
    except exception.CinderException:
        err_msg = _('Create export for volume failed.')
        LOG.exception(err_msg, resource=volume)
        raise exception.VolumeBackendAPIException(data=err_msg)
    try:
        if model_update:
            volume = self.db.volume_update(context, volume_id, model_update)
    except exception.CinderException as ex:
        LOG.exception(_LE('Model update failed.'), resource=volume)
        raise exception.ExportFailure(reason=six.text_type(ex))
    try:
        conn_info = self.driver.initialize_connection(volume, connector)
    except Exception as err:
        err_msg = (_('Driver initialize connection failed (error: %(err)s).') % {'err': six.text_type(err)})
        LOG.error(err_msg, resource=volume)
        self.driver.remove_export(context.elevated(), volume)
        raise exception.VolumeBackendAPIException(data=err_msg)
    typeid = volume['volume_type_id']
    specs = None
    if typeid:
        res = volume_types.get_volume_type_qos_specs(typeid)
        qos = res['qos_specs']
        if (qos and (qos.get('consumer') in ['front-end', 'both'])):
            specs = qos.get('specs')
    qos_spec = dict(qos_specs=specs)
    conn_info['data'].update(qos_spec)
    volume_metadata = self.db.volume_admin_metadata_get(context.elevated(), volume_id)
    access_mode = volume_metadata.get('attached_mode')
    if (access_mode is None):
        access_mode = ('ro' if (volume_metadata.get('readonly') == 'True') else 'rw')
    conn_info['data']['access_mode'] = access_mode
    if (conn_info['data'].get('encrypted') is None):
        encrypted = bool(volume.get('encryption_key_id'))
        conn_info['data']['encrypted'] = encrypted
    if (conn_info['data'].get('discard') is None):
        discard_supported = self.driver.configuration.safe_get('report_discard_supported')
        if discard_supported:
            conn_info['data']['discard'] = True
    LOG.info(_LI('Initialize volume connection completed successfully.'), resource=volume)
    return conn_info
Prepare volume for connection from host represented by connector.

This method calls the driver initialize_connection and returns
it to the caller.  The connector parameter is a dictionary with
information about the host that will connect to the volume in the
following format::

    {
        'ip': ip,
        'initiator': initiator,
    }

ip: the ip address of the connecting machine

initiator: the iscsi initiator name of the connecting machine.
This can be None if the connecting machine does not support iscsi
connections.

driver is responsible for doing any necessary security setup and
returning a connection_info dictionary in the following format::

    {
        'driver_volume_type': driver_volume_type,
        'data': data,
    }

driver_volume_type: a string to identify the type of volume.  This
                   can be used by the calling code to determine the
                   strategy for connecting to the volume. This could
                   be 'iscsi', 'rbd', 'sheepdog', etc.

data: this is the data that the calling code will use to connect
      to the volume. Keep in mind that this will be serialized to
      json in various places, so it should not contain any non-json
      data types.
def initialize_connection(self, context, volume_id, connector):
    "Prepare volume for connection from host represented by connector.\n\n        This method calls the driver initialize_connection and returns\n        it to the caller.  The connector parameter is a dictionary with\n        information about the host that will connect to the volume in the\n        following format::\n\n            {\n                'ip': ip,\n                'initiator': initiator,\n            }\n\n        ip: the ip address of the connecting machine\n\n        initiator: the iscsi initiator name of the connecting machine.\n        This can be None if the connecting machine does not support iscsi\n        connections.\n\n        driver is responsible for doing any necessary security setup and\n        returning a connection_info dictionary in the following format::\n\n            {\n                'driver_volume_type': driver_volume_type,\n                'data': data,\n            }\n\n        driver_volume_type: a string to identify the type of volume.  This\n                           can be used by the calling code to determine the\n                           strategy for connecting to the volume. This could\n                           be 'iscsi', 'rbd', 'sheepdog', etc.\n\n        data: this is the data that the calling code will use to connect\n              to the volume. Keep in mind that this will be serialized to\n              json in various places, so it should not contain any non-json\n              data types.\n        "
    utils.require_driver_initialized(self.driver)
    volume = self.db.volume_get(context, volume_id)
    model_update = None
    try:
        self.driver.validate_connector(connector)
    except exception.InvalidConnectorException as err:
        raise exception.InvalidInput(reason=six.text_type(err))
    except Exception as err:
        err_msg = (_('Validate volume connection failed (error: %(err)s).') % {'err': six.text_type(err)})
        LOG.error(err_msg, resource=volume)
        raise exception.VolumeBackendAPIException(data=err_msg)
    try:
        model_update = self.driver.create_export(context.elevated(), volume, connector)
    except exception.CinderException:
        err_msg = _('Create export for volume failed.')
        LOG.exception(err_msg, resource=volume)
        raise exception.VolumeBackendAPIException(data=err_msg)
    try:
        if model_update:
            volume = self.db.volume_update(context, volume_id, model_update)
    except exception.CinderException as ex:
        LOG.exception(_LE('Model update failed.'), resource=volume)
        raise exception.ExportFailure(reason=six.text_type(ex))
    try:
        conn_info = self.driver.initialize_connection(volume, connector)
    except Exception as err:
        err_msg = (_('Driver initialize connection failed (error: %(err)s).') % {'err': six.text_type(err)})
        LOG.error(err_msg, resource=volume)
        self.driver.remove_export(context.elevated(), volume)
        raise exception.VolumeBackendAPIException(data=err_msg)
    typeid = volume['volume_type_id']
    specs = None
    if typeid:
        res = volume_types.get_volume_type_qos_specs(typeid)
        qos = res['qos_specs']
        if (qos and (qos.get('consumer') in ['front-end', 'both'])):
            specs = qos.get('specs')
    qos_spec = dict(qos_specs=specs)
    conn_info['data'].update(qos_spec)
    volume_metadata = self.db.volume_admin_metadata_get(context.elevated(), volume_id)
    access_mode = volume_metadata.get('attached_mode')
    if (access_mode is None):
        access_mode = ('ro' if (volume_metadata.get('readonly') == 'True') else 'rw')
    conn_info['data']['access_mode'] = access_mode
    if (conn_info['data'].get('encrypted') is None):
        encrypted = bool(volume.get('encryption_key_id'))
        conn_info['data']['encrypted'] = encrypted
    if (conn_info['data'].get('discard') is None):
        discard_supported = self.driver.configuration.safe_get('report_discard_supported')
        if discard_supported:
            conn_info['data']['discard'] = True
    LOG.info(_LI('Initialize volume connection completed successfully.'), resource=volume)
    return conn_info