예제 #1
0
  def ListInstances(self,
                    resource_group_name: Optional[str] = None
                    ) -> Dict[str, compute.AZVirtualMachine]:
    """List instances in an Azure subscription / resource group.

    Args:
      resource_group_name (str): Optional. The resource group name to list
          instances from. If none specified, then all instances in the Azure
          subscription will be listed.

    Returns:
      Dict[str, AZVirtualMachine]: Dictionary mapping instance names (str) to
          their respective AZVirtualMachine object.
    """
    instances = {}  # type: Dict[str, compute.AZVirtualMachine]
    az_vm_client = self.compute_client.virtual_machines
    if not resource_group_name:
      responses = common.ExecuteRequest(az_vm_client, 'list_all')
    else:
      responses = common.ExecuteRequest(
          az_vm_client,
          'list',
          {'resource_group_name': resource_group_name})
    for response in responses:
      for instance in response:
        instances[instance.name] = compute.AZVirtualMachine(
            self,
            instance.id,
            instance.name,
            instance.location,
            zones=instance.zones)
    return instances
예제 #2
0
# pylint: disable=line-too-long
with mock.patch(
        'libcloudforensics.providers.azure.internal.common.GetCredentials'
) as mock_creds:
    mock_creds.return_value = ('fake-subscription-id', mock.Mock())
    with mock.patch(
            'libcloudforensics.providers.azure.internal.account.AZAccount._GetOrCreateResourceGroup'
    ) as mock_resource:
        # pylint: enable=line-too-long
        mock_resource.return_value = 'fake-resource-group'
        FAKE_ACCOUNT = account.AZAccount('fake-resource-group',
                                         default_region='fake-region')

FAKE_INSTANCE = compute.AZVirtualMachine(
    FAKE_ACCOUNT, '/a/b/c/fake-resource-group/fake-vm-name', 'fake-vm-name',
    'fake-region', ['fake-zone'])

FAKE_DISK = compute.AZDisk(FAKE_ACCOUNT,
                           '/a/b/c/fake-resource-group/fake-disk-name',
                           'fake-disk-name', 'fake-region', ['fake-zone'])

FAKE_BOOT_DISK = compute.AZDisk(
    FAKE_ACCOUNT, '/a/b/c/fake-resource-group/fake-boot-disk-name',
    'fake-boot-disk-name', 'fake-region', ['fake-zone'])

FAKE_SNAPSHOT = compute.AZSnapshot(
    FAKE_ACCOUNT, '/a/b/c/fake-resource-group/fake_snapshot_name',
    'fake_snapshot_name', 'fake-region', FAKE_DISK)

MOCK_INSTANCE = mock.Mock(id='/a/b/c/fake-resource-group/fake-vm-name',
예제 #3
0
  def GetOrCreateAnalysisVm(
      self,
      vm_name: str,
      boot_disk_size: int,
      cpu_cores: int,
      memory_in_mb: int,
      ssh_public_key: str,
      region: Optional[str] = None,
      packages: Optional[List[str]] = None,
      tags: Optional[Dict[str, str]] = None
  ) -> Tuple[compute.AZVirtualMachine, bool]:
    """Get or create a new virtual machine for analysis purposes.

    Args:
      vm_name (str): The instance name tag of the virtual machine.
      boot_disk_size (int): The size of the analysis VM boot volume (in GB).
      cpu_cores (int): Number of CPU cores for the analysis VM.
      memory_in_mb (int): The memory size (in MB) for the analysis VM.
      ssh_public_key (str): A SSH public key data to associate with the
          VM. This must be provided as otherwise the VM will not be
          accessible.
      region (str): Optional. The region in which to create the vm. If not
          provided, the vm will be created in the default_region
          associated to the AZAccount object.
      packages (List[str]): Optional. List of packages to install in the VM.
      tags (Dict[str, str]): Optional. A dictionary of tags to add to the
          instance, for example {'TicketID': 'xxx'}. An entry for the
          instance name is added by default.

    Returns:
      Tuple[AWSInstance, bool]: A tuple with an AZVirtualMachine object
          and a boolean indicating if the virtual machine was created
          (True) or reused (False).

    Raises:
      RuntimeError: If the virtual machine cannot be found or created.
    """

    # Re-use instance if it already exists, or create a new one.
    try:
      instance = self.GetInstance(vm_name)
      if instance:
        created = False
        return instance, created
    except RuntimeError:
      pass

    # Validate SSH public key format
    try:
      sshpubkeys.SSHKey(ssh_public_key, strict=True).parse()
    except sshpubkeys.InvalidKeyError as exception:
      raise RuntimeError('The provided public SSH key is invalid: '
                         '{0:s}'.format(str(exception)))

    instance_type = self._GetInstanceType(cpu_cores, memory_in_mb)
    startup_script = utils.ReadStartupScript()
    if packages:
      startup_script = startup_script.replace('${packages[@]}', ' '.join(
          packages))

    if not region:
      region = self.default_region

    creation_data = {
        'location': region,
        'properties': {
            'hardwareProfile': {'vmSize': instance_type},
            'storageProfile': {
                'imageReference': {
                    'sku': '18.04-LTS',
                    'publisher': 'Canonical',
                    'version': 'latest',
                    'offer': 'UbuntuServer'}
            },
            'osDisk': {
                'caching': 'ReadWrite',
                'managedDisk': {'storageAccountType': 'Standard_LRS'},
                'name': 'os-disk-{0:s}'.format(vm_name),
                'diskSizeGb': boot_disk_size,
                'createOption': models.DiskCreateOption.from_image
            },
            'osProfile': {
                'adminUsername': '******',
                'computerName': vm_name,
                # Azure requires the startup script to be sent as a b64 string
                'customData': base64.b64encode(
                    str.encode(startup_script)).decode('utf-8'),
                'linuxConfiguration': {
                    'ssh': {
                        'publicKeys': [{
                            'path': '/home/AzureUser/.ssh/authorized_keys',
                            'keyData': ssh_public_key}]
                    }
                }
            },
            'networkProfile': {
                'networkInterfaces': [
                    {'id': self._CreateNetworkInterfaceForVM(vm_name, region)}
                ]
            }
        }
    }  # type: Dict[str, Any]

    if tags:
      creation_data['tags'] = tags

    try:
      request = self.compute_client.virtual_machines.create_or_update(
          self.default_resource_group_name,
          vm_name,
          creation_data
      )
      while not request.done():
        sleep(5)  # Wait 5 seconds before checking disk status again
      vm = request.result()
    except azure_exceptions.CloudError as exception:
      raise RuntimeError('Could not create instance {0:s}: {1:s}'.format(
          vm_name, str(exception)))

    instance = compute.AZVirtualMachine(self,
                                        vm.id,
                                        vm.name,
                                        vm.location,
                                        zones=vm.zones)
    created = True
    return instance, created