Ejemplo n.º 1
0
    def testGenerateDiskName(self):
        """Test that disk names are correclty generated.

    The disk name must comply with the following RegEx: ^[\\w]{1,80}$
        i.e., it must be between 1 and 80 chars and be within [a-zA-Z0-9].
    """
        disk_name = common.GenerateDiskName(FAKE_SNAPSHOT)
        self.assertEqual('fake_snapshot_name_f4c186ac_copy', disk_name)

        disk_name = common.GenerateDiskName(FAKE_SNAPSHOT,
                                            disk_name_prefix='prefix')
        self.assertEqual('prefix_fake_snapshot_name_f4c186ac_copy', disk_name)
Ejemplo n.º 2
0
    def CreateDiskFromSnapshotURI(
            self,
            snapshot: 'AZComputeSnapshot',
            snapshot_uri: str,
            region: Optional[str] = None,
            disk_name: Optional[str] = None,
            disk_name_prefix: Optional[str] = None,
            disk_type: str = 'Standard_LRS') -> 'AZComputeDisk':
        """Create a new disk based on a SAS snapshot URI.

    This is useful if e.g. one wants to make a copy of a disk in a separate
    Azure account. This method will create a temporary Azure Storage account
    within the destination account, import the snapshot from a downloadable
    link (the source account needs to share the snapshot through a SAS link)
    and then create a disk from the VHD file saved in storage. The Azure
    storage account is then deleted.

    Args:
      snapshot (AZComputeSnapshot): Source snapshot to use.
      snapshot_uri (str): The URI of the snapshot to copy.
      region (str): Optional. The region in which to create the disk. If not
          provided, the disk will be created in the default_region associated to
          the AZAccount object.
      disk_name (str): Optional. String to use as new disk name.
      disk_name_prefix (str): Optional. String to prefix the disk name with.
      disk_type (str): Optional. The sku name for the disk to create. Can be
          Standard_LRS, Premium_LRS, StandardSSD_LRS, or UltraSSD_LRS.
          Default is Standard_LRS.

    Returns:
      AZComputeDisk: Azure Compute Disk.

    Raises:
      RuntimeError: If the disk could not be created.
    """

        if not region:
            region = self.az_account.default_region

        # Create a temporary Azure account storage to import the snapshot
        storage_account_name = hashlib.sha1(
            snapshot.resource_id.encode('utf-8')).hexdigest()[:23]
        storage_account_url = 'https://{0:s}.blob.core.windows.net'.format(
            storage_account_name)
        # pylint: disable=line-too-long
        storage_account_id, storage_account_access_key = self.az_account.storage.CreateStorageAccount(
            storage_account_name, region=region)
        # pylint: enable=line-too-long
        blob_service_client = blob.BlobServiceClient(
            account_url=storage_account_url,
            credential=storage_account_access_key)

        # Create a container within the Storage to receive the imported snapshot
        container_name = storage_account_name + '-container'
        snapshot_vhd_name = snapshot.name + '.vhd'
        container_client = blob_service_client.get_container_client(
            container_name)
        try:
            logger.info('Creating blob container {0:s}'.format(container_name))
            container_client.create_container()
            logger.info('Blob container {0:s} successfully created'.format(
                container_name))
        except exceptions.ResourceExistsError:
            # The container already exists, so we can re-use it
            logger.warning(
                'Reusing existing container: {0:s}'.format(container_name))

        # Download the snapshot from the URI to the storage
        copied_blob = blob_service_client.get_blob_client(
            container_name, snapshot_vhd_name)
        logger.info(
            'Importing snapshot to container from URI {0:s}. '
            'Depending on the size of the snapshot, this process is going '
            'to take a while.'.format(snapshot_uri))
        copied_blob.start_copy_from_url(snapshot_uri)
        copy_status = copied_blob.get_blob_properties().copy.status
        while copy_status != 'success':
            sleep(
                5
            )  # Wait for the vhd to be imported in the Azure storage container
            copy_status = copied_blob.get_blob_properties().copy.status
            if copy_status in ('aborted', 'failed'):
                raise RuntimeError('Could not import the snapshot from URI '
                                   '{0:s}'.format(snapshot_uri))
            logger.debug(
                'Importing snapshot from URI {0:s}'.format(snapshot_uri))
        logger.info('Snapshot successfully imported from URI {0:s}'.format(
            snapshot_uri))

        if not disk_name:
            disk_name = common.GenerateDiskName(
                snapshot, disk_name_prefix=disk_name_prefix)

        # Create a new disk from the imported snapshot
        creation_data = {
            'location': region,
            'creation_data': {
                'source_uri': copied_blob.url,
                'storage_account_id': storage_account_id,
                'create_option': models.DiskCreateOption.import_enum
            },
            'sku': {
                'name': disk_type
            }
        }

        try:
            logger.info('Creating disk: {0:s}'.format(disk_name))
            request = self.compute_client.disks.create_or_update(
                self.az_account.default_resource_group_name, disk_name,
                creation_data)
            while not request.done():
                sleep(5)  # Wait 5 seconds before checking disk status again
            disk = request.result()
            logger.info('Disk {0:s} successfully created'.format(disk_name))
        except azure_exceptions.CloudError as exception:
            raise RuntimeError(
                'Could not create disk from URI {0:s}: {1:s}'.format(
                    snapshot_uri, str(exception)))

        # Cleanup the temporary account storage
        self.az_account.storage.DeleteStorageAccount(storage_account_name)

        return AZComputeDisk(self.az_account, disk.id, disk.name,
                             disk.location, disk.zones)
Ejemplo n.º 3
0
    def CreateDiskFromSnapshot(
            self,
            snapshot: 'AZComputeSnapshot',
            region: Optional[str] = None,
            disk_name: Optional[str] = None,
            disk_name_prefix: Optional[str] = None,
            disk_type: str = 'Standard_LRS') -> 'AZComputeDisk':
        """Create a new disk based on a Snapshot.

    Args:
      snapshot (AZComputeSnapshot): Snapshot to use.
      region (str): Optional. The region in which to create the disk. If not
          provided, the disk will be created in the default_region associated to
          the AZAccount object.
      disk_name (str): Optional. String to use as new disk name.
      disk_name_prefix (str): Optional. String to prefix the disk name with.
      disk_type (str): Optional. The sku name for the disk to create. Can be
          Standard_LRS, Premium_LRS, StandardSSD_LRS, or UltraSSD_LRS. The
          default value is Standard_LRS.

    Returns:
      AZComputeDisk: Azure Compute Disk.

    Raises:
      RuntimeError: If the disk could not be created.
    """

        if not disk_name:
            disk_name = common.GenerateDiskName(
                snapshot, disk_name_prefix=disk_name_prefix)

        if not region:
            region = self.az_account.default_region

        creation_data = {
            'location': region,
            'creation_data': {
                'sourceResourceId': snapshot.resource_id,
                'create_option': models.DiskCreateOption.copy
            },
            'sku': {
                'name': disk_type
            }
        }

        try:
            logger.info('Creating disk: {0:s}'.format(disk_name))
            request = self.compute_client.disks.create_or_update(
                self.az_account.default_resource_group_name, disk_name,
                creation_data)
            while not request.done():
                sleep(5)  # Wait 5 seconds before checking disk status again
            disk = request.result()
            logger.info('Disk {0:s} successfully created'.format(disk_name))
        except azure_exceptions.CloudError as exception:
            raise RuntimeError(
                'Could not create disk from snapshot {0:s}: {1:s}'.format(
                    snapshot.resource_id, str(exception)))

        return AZComputeDisk(self.az_account, disk.id, disk.name,
                             disk.location, disk.zones)