text: # Copyright (C) 2020, Hitachi, Ltd.
  #
  #    Licensed under the Apache License, Version 2.0 (the "License"); you may
  #    not use this file except in compliance with the License. You may obtain
  #    a copy of the License at
  #
  #         http://www.apache.org/licenses/LICENSE-2.0
  #
  #    Unless required by applicable law or agreed to in writing, software
  #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  #    License for the specific language governing permissions and limitations
  #    under the License.
  #
  """iSCSI module for Hitachi HBSD Driver."""
  
  from cinder import interface
  from cinder.volume import driver
  from cinder.volume.drivers.hitachi import hbsd_common as common
  from cinder.volume.drivers.hitachi import hbsd_utils as utils
  from cinder.volume import volume_utils
  
  MSG = utils.HBSDMsg
  
  _DRIVER_INFO = {
      'proto': 'iSCSI',
      'hba_id': 'initiator',
      'hba_id_type': 'iSCSI initiator IQN',
      'msg_id': {
          'target': MSG.CREATE_ISCSI_TARGET_FAILED,
      },
      'volume_backend_name': '%(prefix)siSCSI' % {
          'prefix': utils.DRIVER_PREFIX,
      },
      'volume_opts': [],
      'volume_type': 'iscsi',
  }
  
  
  @interface.volumedriver
  class HBSDISCSIDriver(driver.ISCSIDriver):
      """iSCSI class for Hitachi HBSD Driver.
  
      Version history:
  
      .. code-block:: none
  
          1.0.0 - Initial driver.
          1.1.0 - Add manage_existing/manage_existing_get_size/unmanage methods
          2.0.0 - Major redesign of the driver. This version requires the REST
                  API for communication with the storage backend.
  
      """
  
      VERSION = common.VERSION
  
      # ThirdPartySystems wiki page
      CI_WIKI_NAME = "Hitachi_VSP_CI"
  
      def __init__(self, *args, **kwargs):
          """Initialize instance variables."""
          utils.output_log(MSG.DRIVER_INITIALIZATION_START,
                           driver=self.__class__.__name__,
                           version=self.get_version())
          super(HBSDISCSIDriver, self).__init__(*args, **kwargs)
  
          self.configuration.append_config_values(common.COMMON_VOLUME_OPTS)
          self.common = utils.import_object(
              self.configuration, _DRIVER_INFO, kwargs.get('db'))
  
      def check_for_setup_error(self):
          pass
  
      @volume_utils.trace
      def create_volume(self, volume):
          """Create a volume and return its properties."""
          return self.common.create_volume(volume)
  
      @volume_utils.trace
      def create_volume_from_snapshot(self, volume, snapshot):
          """Create a volume from a snapshot and return its properties."""
          return self.common.create_volume_from_snapshot(volume, snapshot)
  
      @volume_utils.trace
      def create_cloned_volume(self, volume, src_vref):
          """Create a clone of the specified volume and return its properties."""
          return self.common.create_cloned_volume(volume, src_vref)
  
      @volume_utils.trace
      def delete_volume(self, volume):
          """Delete the specified volume."""
          self.common.delete_volume(volume)
  
      @volume_utils.trace
      def create_snapshot(self, snapshot):
          """Create a snapshot from a volume and return its properties."""
          return self.common.create_snapshot(snapshot)
  
      @volume_utils.trace
      def delete_snapshot(self, snapshot):
          """Delete the specified snapshot."""
          self.common.delete_snapshot(snapshot)
  
      def local_path(self, volume):
          pass
  
      def get_volume_stats(self, refresh=False):
          """Return properties, capabilities and current states of the driver."""
          data = self.common.get_volume_stats(refresh)
          if 'pools' in data:
              data["pools"][0]["filter_function"] = self.get_filter_function()
              data["pools"][0]["goodness_function"] = (
                  self.get_goodness_function())
          return data
  
      @volume_utils.trace
      def update_migrated_volume(
              self, ctxt, volume, new_volume, original_volume_status):
          """Do any remaining jobs after migration."""
          self.common.discard_zero_page(new_volume)
          super(HBSDISCSIDriver, self).update_migrated_volume(
              ctxt, volume, new_volume, original_volume_status)
  
      @volume_utils.trace
      def copy_image_to_volume(self, context, volume, image_service, image_id):
          """Fetch the image from image_service and write it to the volume."""
          super(HBSDISCSIDriver, self).copy_image_to_volume(
              context, volume, image_service, image_id)
          self.common.discard_zero_page(volume)
  
      @volume_utils.trace
      def extend_volume(self, volume, new_size):
          """Extend the specified volume to the specified size."""
          self.common.extend_volume(volume, new_size)
  
      @volume_utils.trace
      def manage_existing(self, volume, existing_ref):
          """Return volume properties which Cinder needs to manage the volume."""
          return self.common.manage_existing(volume, existing_ref)
  
      @volume_utils.trace
      def manage_existing_get_size(self, volume, existing_ref):
          """Return the size[GB] of the specified volume."""
          return self.common.manage_existing_get_size(existing_ref)
  
      @volume_utils.trace
      def unmanage(self, volume):
          """Prepare the volume for removing it from Cinder management."""
          self.common.unmanage(volume)
  
      @volume_utils.trace
      def do_setup(self, context):
          """Prepare for the startup of the driver."""
          self.common.do_setup(context)
  
      def ensure_export(self, context, volume):
          """Synchronously recreate an export for a volume."""
          pass
  
      def create_export(self, context, volume, connector):
          """Export the volume."""
          pass
  
      def remove_export(self, context, volume):
          """Remove an export for a volume."""
          pass
  
      def create_export_snapshot(self, context, snapshot, connector):
          pass
  
      def remove_export_snapshot(self, context, snapshot):
          pass
  
      @volume_utils.trace
      def initialize_connection(self, volume, connector):
          """Initialize connection between the server and the volume."""
          return self.common.initialize_connection(volume, connector)
  
      @volume_utils.trace
      def terminate_connection(self, volume, connector, **kwargs):
          """Terminate connection between the server and the volume."""
          if connector is None:
              connector = {}
          if utils.is_shared_connection(volume, connector):
              return
          self.common.terminate_connection(volume, connector)
  
      @volume_utils.trace
      def initialize_connection_snapshot(self, snapshot, connector, **kwargs):
          """Initialize connection between the server and the snapshot."""
          return self.common.initialize_connection(snapshot, connector)
  
      @volume_utils.trace
      def terminate_connection_snapshot(self, snapshot, connector, **kwargs):
          """Terminate connection between the server and the snapshot."""
          self.common.terminate_connection(snapshot, connector)
  
      @volume_utils.trace
      def unmanage_snapshot(self, snapshot):
          """Prepare the snapshot for removing it from Cinder management."""
          return self.common.unmanage_snapshot(snapshot)
  
      @volume_utils.trace
      def retype(self, ctxt, volume, new_type, diff, host):
          """Retype the specified volume."""
          return self.common.retype()
  
      def backup_use_temp_snapshot(self):
          return True
  
      @volume_utils.trace
      def revert_to_snapshot(self, context, volume, snapshot):
          """Rollback the specified snapshot"""
          return self.common.revert_to_snapshot(volume, snapshot)
  