# Path: libcloudforensics/logging_utils.py
# def _GenerateColorSequences() -> List[str]:
#   def __init__(self,
#                colorize: bool = True,
#                random_color: bool = False,
#                **kwargs: str) -> None:
#   def format(self, record: logging.LogRecord) -> str:
# def SetUpLogger(name: str, no_newline: bool = False) -> None:
# def GetLogger(name: str) -> logging.Logger:
# COLOR_SEQS = _GenerateColorSequences()
# RESET_SEQ = '\u001b[0m'
# BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = COLOR_SEQS[8:16]
# BG_RED = '\u001b[41m'  # Red background
# BOLD = '\u001b[1m'  # Bold / bright modifier
# LOG_FORMAT = ('[%(asctime)s] [{0:s}{color:s}%(name)-20s{1:s}] %(levelname)-8s'
#               ' %(message)s')
# LEVEL_COLOR_MAP = {
#     'WARNING': YELLOW,
#     'INFO': WHITE,
#     'DEBUG': BLUE,
#     'CRITICAL': BOLD + BG_RED + WHITE,
#     'ERROR': RED
# }
# class Formatter(logging.Formatter):
# 
# Path: libcloudforensics/errors.py
# class LCFError(Exception):
# class CredentialsConfigurationError(LCFError):
# class InvalidFileFormatError(LCFError):
# class InvalidNameError(LCFError):
# class ResourceNotFoundError(LCFError):
# class ResourceCreationError(LCFError):
# class ResourceDeletionError(LCFError):
# class InstanceStateChangeError(LCFError):
# class ServiceAccountRemovalError(LCFError):
# class InstanceProfileCreationError(LCFError):
# class OperationFailedError(LCFError):
# class TransferCreationError(LCFError):
# class TransferExecutionError(LCFError):
# class ResourceAlreadyExistsError(LCFError):
#   def __init__(self,
#                message: str,
#                name: str) -> None:
# 
# Path: libcloudforensics/providers/azure/internal/compute_base_resource.py
# class AZComputeResource:
#   def __init__(self,
#                az_account: 'account.AZAccount',
#                resource_id: str,
#                name: str,
#                region: str,
#                zones: Optional[List[str]] = None) -> None:
#   def compute_client(self) -> compute_sdk.ComputeManagementClient:
# 
# Path: libcloudforensics/providers/azure/internal/common.py
# REGEX_DISK_NAME = re.compile('^[\\w]{1,80}$')
# REGEX_SNAPSHOT_NAME = re.compile('^(?=.{1,80}$)[a-zA-Z0-9]([\\w,-]*[\\w])?$')
# REGEX_ACCOUNT_STORAGE_NAME = re.compile('^[a-z0-9]{1,24}$')
# REGEX_COMPUTE_RESOURCE_ID = re.compile(
#     '/subscriptions/.+/resourceGroups/.+/providers/Microsoft.Compute/.+/.+')
# DEFAULT_DISK_COPY_PREFIX = 'evidence'
# UBUNTU_1804_SKU = '18.04-LTS'
# def _ParseCredentialsFile(profile_name: str) -> Dict[str, Any]:
# def _CheckAzureCliCredentials() -> Optional[str]:
# def GetCredentials(profile_name: Optional[str] = None
#                    ) -> Tuple[str, DefaultAzureCredential]:
# def ExecuteRequest(
#     client: Any,
#     func: str,
#     kwargs: Optional[Dict[str, str]] = None) -> List[Any]:
# def GenerateDiskName(snapshot: 'compute.AZComputeSnapshot',
#                      disk_name_prefix: Optional[str] = None) -> str:
# 
# Path: libcloudforensics/scripts/utils.py
# FORENSICS_STARTUP_SCRIPT = 'forensics_packages_startup.sh'
# FORENSICS_STARTUP_SCRIPT_AWS = 'forensics_packages_startup_aws.sh'
# FORENSICS_STARTUP_SCRIPT_GCP = FORENSICS_STARTUP_SCRIPT
# FORENSICS_STARTUP_SCRIPT_AZ = FORENSICS_STARTUP_SCRIPT
# EBS_SNAPSHOT_COPY_SCRIPT_AWS = 'ebs_snapshot_copy_aws.sh'
# def ReadStartupScript(filename: Optional[str] = '') -> str:


import base64
import hashlib
import sshpubkeys
from time import sleep
from typing import Optional, List, Dict, TYPE_CHECKING, Tuple, Any
from msrestazure import azure_exceptions
from azure.storage import blob
from azure.core import exceptions
from azure.mgmt import compute as compute_sdk
from azure.mgmt.compute.v2020_05_01 import models
from libcloudforensics import logging_utils
from libcloudforensics import errors
from libcloudforensics.providers.azure.internal import compute_base_resource  # pylint: disable=line-too-long, ungrouped-imports
from libcloudforensics.providers.azure.internal import common  # pylint: disable=line-too-long, ungrouped-imports
from libcloudforensics.scripts import utils
  from libcloudforensics.providers.azure.internal import account  # pylint: disable=cyclic-import
    return disks[disk_name]

  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:
      ResourceCreationError: If the disk could not be created.
    """

    if not disk_name:

# Path: libcloudforensics/logging_utils.py
# def _GenerateColorSequences() -> List[str]:
#   def __init__(self,
#                colorize: bool = True,
#                random_color: bool = False,
#                **kwargs: str) -> None:
#   def format(self, record: logging.LogRecord) -> str:
# def SetUpLogger(name: str, no_newline: bool = False) -> None:
# def GetLogger(name: str) -> logging.Logger:
# COLOR_SEQS = _GenerateColorSequences()
# RESET_SEQ = '\u001b[0m'
# BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = COLOR_SEQS[8:16]
# BG_RED = '\u001b[41m'  # Red background
# BOLD = '\u001b[1m'  # Bold / bright modifier
# LOG_FORMAT = ('[%(asctime)s] [{0:s}{color:s}%(name)-20s{1:s}] %(levelname)-8s'
#               ' %(message)s')
# LEVEL_COLOR_MAP = {
#     'WARNING': YELLOW,
#     'INFO': WHITE,
#     'DEBUG': BLUE,
#     'CRITICAL': BOLD + BG_RED + WHITE,
#     'ERROR': RED
# }
# class Formatter(logging.Formatter):
# 
# Path: libcloudforensics/errors.py
# class LCFError(Exception):
# class CredentialsConfigurationError(LCFError):
# class InvalidFileFormatError(LCFError):
# class InvalidNameError(LCFError):
# class ResourceNotFoundError(LCFError):
# class ResourceCreationError(LCFError):
# class ResourceDeletionError(LCFError):
# class InstanceStateChangeError(LCFError):
# class ServiceAccountRemovalError(LCFError):
# class InstanceProfileCreationError(LCFError):
# class OperationFailedError(LCFError):
# class TransferCreationError(LCFError):
# class TransferExecutionError(LCFError):
# class ResourceAlreadyExistsError(LCFError):
#   def __init__(self,
#                message: str,
#                name: str) -> None:
# 
# Path: libcloudforensics/providers/azure/internal/compute_base_resource.py
# class AZComputeResource:
#   def __init__(self,
#                az_account: 'account.AZAccount',
#                resource_id: str,
#                name: str,
#                region: str,
#                zones: Optional[List[str]] = None) -> None:
#   def compute_client(self) -> compute_sdk.ComputeManagementClient:
# 
# Path: libcloudforensics/providers/azure/internal/common.py
# REGEX_DISK_NAME = re.compile('^[\\w]{1,80}$')
# REGEX_SNAPSHOT_NAME = re.compile('^(?=.{1,80}$)[a-zA-Z0-9]([\\w,-]*[\\w])?$')
# REGEX_ACCOUNT_STORAGE_NAME = re.compile('^[a-z0-9]{1,24}$')
# REGEX_COMPUTE_RESOURCE_ID = re.compile(
#     '/subscriptions/.+/resourceGroups/.+/providers/Microsoft.Compute/.+/.+')
# DEFAULT_DISK_COPY_PREFIX = 'evidence'
# UBUNTU_1804_SKU = '18.04-LTS'
# def _ParseCredentialsFile(profile_name: str) -> Dict[str, Any]:
# def _CheckAzureCliCredentials() -> Optional[str]:
# def GetCredentials(profile_name: Optional[str] = None
#                    ) -> Tuple[str, DefaultAzureCredential]:
# def ExecuteRequest(
#     client: Any,
#     func: str,
#     kwargs: Optional[Dict[str, str]] = None) -> List[Any]:
# def GenerateDiskName(snapshot: 'compute.AZComputeSnapshot',
#                      disk_name_prefix: Optional[str] = None) -> str:
# 
# Path: libcloudforensics/scripts/utils.py
# FORENSICS_STARTUP_SCRIPT = 'forensics_packages_startup.sh'
# FORENSICS_STARTUP_SCRIPT_AWS = 'forensics_packages_startup_aws.sh'
# FORENSICS_STARTUP_SCRIPT_GCP = FORENSICS_STARTUP_SCRIPT
# FORENSICS_STARTUP_SCRIPT_AZ = FORENSICS_STARTUP_SCRIPT
# EBS_SNAPSHOT_COPY_SCRIPT_AWS = 'ebs_snapshot_copy_aws.sh'
# def ReadStartupScript(filename: Optional[str] = '') -> str:


# Path: libcloudforensics/providers/azure/internal/compute.py
import base64
import hashlib
import sshpubkeys
from time import sleep
from typing import Optional, List, Dict, TYPE_CHECKING, Tuple, Any
from msrestazure import azure_exceptions
from azure.storage import blob
from azure.core import exceptions
from azure.mgmt import compute as compute_sdk
from azure.mgmt.compute.v2020_05_01 import models
from libcloudforensics import logging_utils
from libcloudforensics import errors
from libcloudforensics.providers.azure.internal import compute_base_resource  # pylint: disable=line-too-long, ungrouped-imports
from libcloudforensics.providers.azure.internal import common  # pylint: disable=line-too-long, ungrouped-imports
from libcloudforensics.scripts import utils
  from libcloudforensics.providers.azure.internal import account  # pylint: disable=cyclic-import

    return disks[disk_name]

  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:
      ResourceCreationError: If the disk could not be created.
    """

    if not disk_name:

      disk_name = common.GenerateDiskName(snapshot,