in source/code/actions/ec2_delete_snapshot_action.py [0:0]
def execute(self):
def get_start_time(sn):
if isinstance(sn["StartTime"], datetime):
return sn["StartTime"]
return dateutil.parser.parse(sn["StartTime"])
def snapshots_to_delete():
def by_retention_days():
delete_before_dt = self._datetime_.utcnow().replace(tzinfo=pytz.timezone("UTC")) - timedelta(
days=int(self.retention_days))
self._logger_.info(INF_RETENTION_DAYS, delete_before_dt)
for sn in sorted(self.snapshots, key=lambda snap: snap["Region"]):
snapshot_dt = get_start_time(sn)
if snapshot_dt < delete_before_dt:
self._logger_.debug(DEBUG_SN_RETENTION_DAYS_DELETE, sn["SnapshotId"], get_start_time(sn),
sn["VolumeId"], self.retention_days)
yield sn
else:
self._logger_.debug(DEBUG_SN_RETENTION_DAYS_KEEP, sn, s, ["VolumeId"],
get_start_time(sn), delete_before_dt.isoformat())
def by_retention_count():
self._logger_.info(INF_KEEP_RETENTION_COUNT, self.retention_count)
sorted_snapshots = sorted(self.snapshots,
key=lambda snap: (snap["VolumeId"], snap["StartTime"]),
reverse=True)
volume = None
count_for_volume = 0
for sn in sorted_snapshots:
if sn["VolumeId"] != volume:
volume = sn["VolumeId"]
count_for_volume = 0
count_for_volume += 1
if count_for_volume > self.retention_count:
self._logger_.debug(DEBUG_SN_DELETE_RETENTION_COUNT,
sn["SnapshotId"],
sn["StartTime"],
sn["VolumeId"],
count_for_volume)
yield sn
else:
self._logger_.debug(DEBUG_SN_KEEP_RETENTION_COUNT,
sn["SnapshotId"],
sn["StartTime"],
sn["VolumeId"],
count_for_volume)
return list(by_retention_days()) if self.retention_days != 0 else list(by_retention_count())
self._logger_.info("{}, version {}", self.properties[ACTION_TITLE], self.properties[ACTION_VERSION])
deleted_count = 0
self._logger_.debug("Snapshots : {}", self.snapshots)
snapshot_id = ""
self._logger_.info(INF_SNAPSHOTS_FOR_VOLUME,
",".join(["{} ({})".format(s["SnapshotId"], s["StartTime"]) for s in self.snapshots]),
self.snapshots[0].get("VolumeId", ""))
ec2 = services.create_service("ec2", session=self._session_,
service_retry_strategy=get_default_retry_strategy("ec2", context=self._context_))
for deleted_snapshot in snapshots_to_delete():
if self.time_out():
break
if "deleted" not in self.result:
self.result["deleted"] = {}
self.result["deleted"][self._region_] = []
try:
snapshot_id = deleted_snapshot["SnapshotId"]
if ec2.get(services.ec2_service.SNAPSHOTS,
region=self._region_,
SnapshotIds=[snapshot_id]) is None:
self._logger_.info(INF_NO_LONGER_AVAILABLE, snapshot_id)
else:
self.ec2_client.delete_snapshot_with_retries(DryRun=self.dryrun,
SnapshotId=snapshot_id,
_expected_boto3_exceptions_=["InvalidSnapshot.NotFound"])
time.sleep(0.2)
deleted_count += 1
copied = deleted_snapshot.get("IsCopied", False)
self._logger_.info(INF_SNAPSHOT_DELETED, "copied " if copied else "", snapshot_id, deleted_snapshot["VolumeId"])
self.result["deleted"][self._region_].append(snapshot_id)
except ClientError as ex_client:
if ex_client.response.get("Error", {}).get("Code", "") == "InvalidSnapshot.NotFound":
self._logger_.info(INF_SNAPSHOT_NOT_FOUND, snapshot_id)
else:
raise ex_client
except Exception as ex:
if self.dryrun:
self._logger_.debug(str(ex))
self.result["delete_snapshot"] = str(ex)
return self.result
else:
raise ex
self.result.update({
"snapshots": len(self.snapshots),
"snapshots-deleted": deleted_count,
METRICS_DATA: build_action_metrics(self, DeletedSnapshots=deleted_count)
})
return self.result