{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "a07655e8", "metadata": {}, "outputs": [], "source": [ "import boto3\n", "import logging\n", "import pytz\n", "import datetime\n", "import sys\n", "\n", "logging.basicConfig(\n", " format='%(levelname)s:%(message)s', level=logging.WARNING)\n", "logger = logging.getLogger(__name__)\n", "\n", "utc=pytz.UTC\n", "\n", "list_all_restored_objects = False\n", "\n", "s3 = boto3.resource('s3')\n", "\n", "# TODO: replace name-of-the-bucket with bucket name\n", "bucket_name = 'name-of-the-bucket'\n", "\n", "if bucket_name == 'name-of-the-bucket':\n", " logger.error(\"Please, set bucket_name before running this script\")\n", " sys.exit(1)\n", "\n", "#TODO: replace date and time accordingly\n", "# Syntax:\n", "# datetime(year, month, day, hour, minute, second, microsecond, UTC-00:00)\n", "# Example:\n", "# point_of_restore = datetime.datetime(2022, 5, 6, 16, 0, 0, 0, pytz.UTC)\n", "\n", "try:\n", " logger.info(\"Variable point_of_restore has been set as %s\", point_of_restore)\n", "except:\n", " logger.error(\"Please, set point_of_restore before running this script\")\n", " raise\n", "\n", " \n", "bucket_versioning = s3.meta.client.get_bucket_versioning(Bucket=bucket_name)\n", " \n", "count = 0\n", "\n", "\n", "\n", "def revive_object(bucket, object_key):\n", " \"\"\"\n", " Revives a versioned object that was deleted by removing the object's active\n", " delete marker.\n", " A versioned object presents as deleted when its latest version is a delete marker.\n", " By removing the delete marker, we make the previous version the latest version\n", " and the object then presents as *not* deleted.\n", "\n", " :param bucket: The bucket that contains the object.\n", " :param object_key: The object to revive.\n", " \"\"\"\n", " # Get the latest version for the object.\n", " response = s3.meta.client.list_object_versions(\n", " Bucket=bucket.name, Prefix=object_key, MaxKeys=1)\n", "\n", " if 'DeleteMarkers' in response:\n", " latest_version = response['DeleteMarkers'][0]\n", " if latest_version['IsLatest']:\n", " logger.info(\"Object %s was deleted on %s. \", object_key, latest_version['LastModified'])\n", "\n", " last_modified = latest_version['LastModified']\n", "\n", " if point_of_restore < last_modified:\n", " logger.info(\"Object was deleted after point of restore. Activation will continue for object %s \",\n", " object_key)\n", " \n", " obj = bucket.Object(object_key)\n", " obj.Version(latest_version['VersionId']).delete()\n", " \n", " global count\n", " count += 1\n", " \n", " if list_all_restored_objects:\n", " logger.warning(\"Revived %s\", object_key)\n", " else:\n", " logger.info(\"Object was deleted before point of restore. Activation will NOT continue for object %s \",\n", " object_key)\n", " else:\n", " logger.info(\"Delete marker is not the latest version for %s!\",\n", " object_key)\n", " elif 'Versions' in response:\n", " logger.info(\"Got an active version for %s, nothing to do.\", object_key)\n", " else:\n", " logger.error(\"Couldn't get any version info for %s.\", object_key)\n", " \n", "\n", "bucket = s3.Bucket(bucket_name) \n", "\n", "is_trunckated = True\n", "next_key_marker = \"\"\n", "next_version_id_marker = \"\"\n", "\n", "logger.warning(\"Processing of bucket %s has started.\", bucket_name)\n", "\n", "while is_trunckated:\n", " \n", " if next_key_marker:\n", " \n", " all_objects = s3.meta.client.list_object_versions(Bucket=bucket.name, KeyMarker=next_key_marker, VersionIdMarker = next_version_id_marker)\n", " \n", " else:\n", " \n", " all_objects = s3.meta.client.list_object_versions(Bucket=bucket.name)\n", " \n", "\n", " if 'Versions' in all_objects:\n", " all_versions = all_objects['Versions']\n", "\n", " for version in all_versions:\n", " if not version['IsLatest']:\n", " revive_object(bucket, version['Key'])\n", "\n", " is_trunckated = all_objects['IsTruncated']\n", " if is_trunckated:\n", " next_key_marker = all_objects['NextKeyMarker']\n", " next_version_id_marker = all_objects['NextVersionIdMarker']\n", " \n", "logger.warning(\"Processing of bucket %s has been completed. %d files have been restored\", bucket_name, count)\n", "\n" ] } ], "metadata": { "kernelspec": { "display_name": "conda_python3", "language": "python", "name": "conda_python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.13" } }, "nbformat": 4, "nbformat_minor": 5 }