Esempio n. 1
0
def CleanUp(project_id, zone, instance_name):
    """Clean up GCP project.

  Remove the instance [instance_name] in the GCP project [project_id] and its
  disks that were created as part of the end to end test.

  Attributes:
    project_id (str): the project id of the GCP project.
    zone (str): the zone for the project.
    instance_name (str): the name of the analysis VM to remove.
  """

    gcp_client = common.GoogleCloudComputeClient(project_id=project_id)
    project = gcp_project.GoogleCloudProject(project_id, zone)
    disks = compute.GoogleComputeInstance(project.project_id, zone,
                                          instance_name).ListDisks()

    # delete the created forensics VMs
    log.info('Deleting analysis instance: {0:s}.'.format(instance_name))
    gce_instances_client = gcp_client.GceApi().instances()
    request = gce_instances_client.delete(project=project.project_id,
                                          zone=project.default_zone,
                                          instance=instance_name)
    try:
        request.execute()
    except HttpError:
        # GceOperation triggers a while(True) loop that checks on the
        # operation ID. Sometimes it loops one more time right when the
        # operation has finished and thus the associated ID doesn't exists
        # anymore, throwing an HttpError. We can ignore this.
        pass
    log.info('Instance {0:s} successfully deleted.'.format(instance_name))

    # delete the copied disks
    # we ignore the disk that was created for the analysis VM (disks[0]) as
    # it is deleted in the previous operation
    gce_disks_client = gcp_client.GceApi().disks()
    for disk in list(disks.keys())[1:]:
        log.info('Deleting disk: {0:s}.'.format(disk))
        while True:
            try:
                request = gce_disks_client.delete(project=project.project_id,
                                                  zone=project.default_zone,
                                                  disk=disk)
                request.execute()
                break
            except HttpError as exception:
                # GceApi() will throw a 400 error until the analysis VM deletion is
                # correctly propagated. When the disk is finally deleted, it will
                # throw a 404 not found if it looped again after deletion.
                if exception.resp.status == 404:
                    break
                if exception.resp.status != 400:
                    log.warning(
                        'Could not delete the disk {0:s}: {1:s}'.format(
                            disk, str(exception)))
                # Throttle the requests to one every 10 seconds
                time.sleep(10)

        log.info('Disk {0:s} successfully deleted.'.format(disk))
Esempio n. 2
0
  def test_end_to_end_boot_disk(self):
    """End to end test on GCP.

    This end-to-end test runs directly on GCP and tests that:
      1. The project.py module connects to the target instance and makes a
            snapshot of the boot disk.
      2. A new disk is created from the taken snapshot.
      3. If an analysis VM already exists, the module will attach the disk
            copy to the VM. Otherwise, it will create a new GCP instance for
            analysis purpose and attach the boot disk copy to it.
    """

    # Make a copy of the boot disk of the instance to analyse
    self.boot_disk_copy = forensics.CreateDiskCopy(
        src_proj=self.project_id,
        dst_proj=self.project_id,
        instance_name=self.instance_to_analyse,
        zone=self.zone,
        # disk_name=None by default, boot disk will be copied
    )

    gcp_client_api = common.GoogleCloudComputeClient(self.project_id).GceApi()

    # The disk copy should be attached to the analysis project
    gce_disk_client = gcp_client_api.disks()
    request = gce_disk_client.get(
        project=self.project_id, zone=self.zone, disk=self.boot_disk_copy.name)
    result = request.execute()
    self.assertEqual(result['name'], self.boot_disk_copy.name)

    # Get the analysis VM and attach the evidence boot disk
    self.analysis_vm, _ = forensics.StartAnalysisVm(
        project=self.project_id,
        vm_name=self.analysis_vm_name,
        zone=self.zone,
        boot_disk_size=10,
        boot_disk_type='pd-ssd',
        cpu_cores=4,
        attach_disks=[self.boot_disk_copy.name])

    # The forensic instance should be live in the analysis GCP project and
    # the disk should be attached
    gce_instance_client = gcp_client_api.instances()
    request = gce_instance_client.get(
        project=self.project_id, zone=self.zone, instance=self.analysis_vm_name)
    result = request.execute()
    self.assertEqual(result['name'], self.analysis_vm_name)

    for disk in result['disks']:
      if disk['boot']:
        request = gce_disk_client.get(project=self.project_id,
                                      zone=self.zone,
                                      disk=disk['source'].split('/')[-1])
        boot_disk = request.execute()
        self.assertEqual('pd-ssd', boot_disk['type'].rsplit('/', 1)[-1])
      if disk['source'].split('/')[-1] == self.boot_disk_copy.name:
        return
    self.fail(
        'Error: could not find the disk {0:s} in instance {1:s}'.format(
            self.boot_disk_copy.name, self.analysis_vm_name))
Esempio n. 3
0
    def tearDownClass(cls):
        analysis_vm = cls.analysis_vm
        zone = cls.zone
        project = cls.gcp
        disks = analysis_vm.ListDisks()
        gcp_client = common.GoogleCloudComputeClient(project.project_id)
        # delete the created forensics VMs
        common.LOGGER.info('Deleting analysis instance: {0:s}.'.format(
            analysis_vm.name))
        gce_instance_client = gcp_client.GceApi().instances()
        request = gce_instance_client.delete(project=project.project_id,
                                             zone=zone,
                                             instance=analysis_vm.name)
        response = request.execute()
        try:
            gcp_client.BlockOperation(response)
        except HttpError:
            # BlockOperation triggers a while(True) loop that checks on the
            # operation ID. Sometimes it loops one more time right when the
            # operation has finished and thus the associated ID doesn't exists
            # anymore, throwing an HttpError. We can ignore this.
            pass
        common.LOGGER.info('Instance {0:s} successfully deleted.'.format(
            analysis_vm.name))

        # delete the copied disks
        # we ignore the disk that was created for the analysis VM (disks[0]) as
        # it is deleted in the previous operation
        for disk in list(disks.keys())[1:]:
            common.LOGGER.info('Deleting disk: {0:s}.'.format(disk))
            while True:
                try:
                    gce_disk_client = gcp_client.GceApi().disks()
                    request = gce_disk_client.delete(
                        project=project.project_id, zone=zone, disk=disk)
                    response = request.execute()
                    gcp_client.BlockOperation(response)
                    break
                except HttpError as exception:
                    # The gce api will throw a 400 until the analysis vm's deletion is
                    # correctly propagated. When the disk is finally deleted, it will
                    # throw a 404 not found if it looped one more time after deletion.
                    if exception.resp.status == 404:
                        break
                    if exception.resp.status != 400:
                        common.LOGGER.warning(
                            'Could not delete the disk {0:s}: {1:s}'.format(
                                disk, str(exception)))
                    # Throttle the requests to one every 10 seconds
                    time.sleep(10)

            common.LOGGER.info('Disk {0:s} successfully deleted.'.format(disk))
Esempio n. 4
0
 def __init__(self, *args, **kwargs):
     super(EndToEndTest, self).__init__(*args, **kwargs)
     try:
         project_info = ReadProjectInfo()
     except (OSError, RuntimeError, ValueError) as exception:
         self.error_msg = str(exception)
         return
     self.project_id = project_info['project_id']
     self.instance_to_analyse = project_info['instance']
     # Optional: test a disk other than the boot disk
     self.disk_to_forensic = project_info.get('disk', None)
     self.zone = project_info['zone']
     self.gcp_client = common.GoogleCloudComputeClient(
         project_id=self.project_id)