def CreateDiskCopy(
    src_proj: str,
    dst_proj: str,
    zone: str,
    instance_name: Optional[str] = None,
    disk_name: Optional[str] = None,
    disk_type: Optional[str] = None) -> 'compute.GoogleComputeDisk':
  """Creates a copy of a Google Compute Disk.

  Args:
    src_proj (str): Name of project that holds the disk to be copied.
    dst_proj (str): Name of project to put the copied disk in.
    zone (str): Zone where the new disk is to be created.
    instance_name (str): Optional. Instance using the disk to be copied.
    disk_name (str): Optional. Name of the disk to copy. If None,
        instance_name must be specified and the boot disk will be copied.
    disk_type (str): Optional. URL of the disk type resource describing
        which disk type to use to create the disk. The default behavior is to
        use the same disk type as the source disk.

  Returns:
    GoogleComputeDisk: A Google Compute Disk object.

  Raises:
    ResourceNotFoundError: If the GCP resource is not found.
    CredentialsConfigurationError: If the library could not authenticate to GCP.
    RuntimeError: If an unknown HttpError is thrown.
    ResourceCreationError: If there are errors copying the disk.
    ValueError: If both instance_name and disk_name are missing.
  """

  if not instance_name and not disk_name:
    raise ValueError(
        'You must specify at least one of [instance_name, disk_name].')

  src_project = gcp_project.GoogleCloudProject(src_proj)
  dst_project = gcp_project.GoogleCloudProject(dst_proj, default_zone=zone)

  try:
    if disk_name:
      disk_to_copy = src_project.compute.GetDisk(disk_name)
    elif instance_name:
      instance = src_project.compute.GetInstance(instance_name)
      disk_to_copy = instance.GetBootDisk()

    if not disk_type:
      disk_type = disk_to_copy.GetDiskType()

    logger.info('Disk copy of {0:s} started...'.format(disk_to_copy.name))
    snapshot, created = disk_to_copy.Snapshot()
    logger.debug('Snapshot created: {0:s}'.format(snapshot.name))
    new_disk = dst_project.compute.CreateDiskFromSnapshot(
        snapshot, disk_name_prefix='evidence', disk_type=disk_type)
    logger.info(
        'Disk {0:s} successfully copied to {1:s}'.format(
            disk_to_copy.name, new_disk.name))
    if created:
      snapshot.Delete()
      logger.debug('Snapshot {0:s} deleted.'.format(snapshot.name))

  except (RefreshError, DefaultCredentialsError) as exception:
    raise errors.CredentialsConfigurationError(
        'Something is wrong with your Application Default Credentials. Try '
        'running: $ gcloud auth application-default login: {0!s}'.format(
            exception),
        __name__) from exception
  except HttpError as exception:
    if exception.resp.status == 403:
      raise errors.CredentialsConfigurationError(
          'Make sure you have the appropriate permissions on the project: '
          '{0!s}'.format(exception),
          __name__) from exception
    if exception.resp.status == 404:
      raise errors.ResourceNotFoundError(
          'GCP resource not found. Maybe a typo in the project / instance / '
          'disk name?',
          __name__) from exception
    raise RuntimeError(exception) from exception
  except RuntimeError as exception:
    raise errors.ResourceCreationError(
        'Cannot copy disk "{0:s}": {1!s}'.format(disk_name, exception),
        __name__) from exception

  return new_disk
Creates a copy of a Google Compute Disk.

Args:
src_proj (str): Name of project that holds the disk to be copied.
dst_proj (str): Name of project to put the copied disk in.
zone (str): Zone where the new disk is to be created.
instance_name (str): Optional. Instance using the disk to be copied.
disk_name (str): Optional. Name of the disk to copy. If None,
instance_name must be specified and the boot disk will be copied.
disk_type (str): Optional. URL of the disk type resource describing
which disk type to use to create the disk. The default behavior is to
use the same disk type as the source disk.

Returns:
GoogleComputeDisk: A Google Compute Disk object.

Raises:
ResourceNotFoundError: If the GCP resource is not found.
CredentialsConfigurationError: If the library could not authenticate to GCP.
RuntimeError: If an unknown HttpError is thrown.
ResourceCreationError: If there are errors copying the disk.
ValueError: If both instance_name and disk_name are missing.
libcloudforensics/providers/gcp/forensics.py