Python EC2 快照脚本,使用 datetime 删除旧快照

Python script for EC2 snapshots, use datetime to delete old snapshots

我是 Python 的新手,我编写了一个 python 脚本,该脚本拍摄指定卷的快照,然后仅保留为该卷请求的快照数量。

#Built with Python 3.3.2
import boto.ec2
from boto.ec2.connection import EC2Connection
from boto.ec2.regioninfo import RegionInfo
from boto.ec2.snapshot import Snapshot
from datetime import datetime
from functools import cmp_to_key
import sys

aws_access_key = str(input("AWS Access Key: "))
aws_secret_key = str(input("AWS Secret Key: "))
regionname = str(input("AWS Region Name: "))
regionendpoint = str(input("AWS Region Endpoint: "))
region = RegionInfo(name=regionname, endpoint=regionendpoint)
conn = EC2Connection(aws_access_key_id = aws_access_key, aws_secret_access_key = aws_secret_key, region = region)
print (conn)

volumes = conn.get_all_volumes()
print ("%s" % repr(volumes))

vol_id = str(input("Enter Volume ID to snapshot: "))
keep = int(input("Enter number of snapshots to keep:  "))
volume = volumes[0]
description = str(input("Enter volume snapshot description: "))


if volume.create_snapshot(description):
    print ('Snapshot created with description: %s' % description)

snapshots = volume.snapshots()
print (snapshots)

def date_compare(snap1, snap2):
    if snap1.start_time < snap2.start_time:
        return -1
    elif snap1.start_time == snap2.start_time:
        return 0
    return 1

snapshots.sort(key=cmp_to_key(date_compare))
delta = len(snapshots) - keep
for i in range(delta):
    print ('Deleting snapshot %s' % snapshots[i].description)
    snapshots[i].delete()

我现在想做的不是使用要保留的快照数量,而是想将其更改为指定要保留的快照的日期范围。例如,删除任何早于特定日期和时间的内容。我有点知道从哪里开始,基于上面的脚本我有按日期排序的快照列表。我想要做的是提示用户指定删除快照的日期和时间,例如 2015-3-4 14:00:00 任何早于此的内容都将被删除。希望有人可以让我在这里开始

谢谢!!

首先,您可以提示用户指定删除快照的日期和时间。

import datetime
user_time = str(input("Enter datetime from when you want to delete, like this format 2015-3-4 14:00:00:"))
real_user_time = datetime.datetime.strptime(user_time, '%Y-%m-%d %H:%M:%S')
print real_user_time  # as you can see here, user time has been changed from a string to a datetime object

其次,删除比这更早的任何内容

解决方案一:

for snap in snapshots:
    start_time = datetime.datetime.strptime(snap.start_time[:-5], '%Y-%m-%dT%H:%M:%S')
    if start_time > real_user_time:
        snap.delete()

解决方案二:

由于快照已排序,您只能找到早于 real_user_time 的第一个快照并删除所有其余快照。

snap_num = len(snapshots)
for i in xrange(snap_num):
    # if snapshots[i].start_time is not the format of datetime object, you will have to format it first like above
    start_time = datetime.datetime.strptime(snapshots[i].start_time[:-5], '%Y-%m-%dT%H:%M:%S')
    if start_time > real_user_time:
        for n in xrange(i,snap_num):
            snapshots[n].delete()
        break

希望对您有所帮助。 :)

小心。确保规范化开始时间值(例如,将它们转换为 UTC)。将用户本地时区的时间与服务器上使用的任何时区进行比较是没有意义的。此外,本地时区在不同时间可能有不同的 utc 偏移量。参见 Find if 24 hrs have passed between datetimes - Python

如果所有日期都是 UTC,那么您可以将快照排序为:

from operator import attrgetter

snapshots.sort(key=attrgetter('start_time'))

如果 snapshots 已排序,那么您可以 "delete anything older than a specific date & time" 使用 bisect 模块:

from bisect import bisect

class Seq(object):
    def __init__(self, seq):
        self.seq = seq
    def __len__(self):
        return len(self.seq)
    def __getitem__(self, i):
        return self.seq[i].start_time

del snapshots[:bisect(Seq(snapshots), given_time)]

它删除所有带有 start_time <= given_time 的快照。


您也可以在不排序的情况下删除旧快照:

snapshots[:] = [s for s in snapshots if s.start_time > given_time]

如果您想在不更改 snapshots 列表的情况下显式调用 .delete() 方法:

for s in snapshots:
    if s.start_time <= given_time:
        s.delete()

如果s.start_time是一个使用2015-03-04T06:35:18.000Z格式的字符串那么given_time也应该是那种格式(注意:Z这里表示时间是UTC ) 如果用户使用不同的时区;您必须在比较之前转换时间(str -> datetime -> datetime in utc -> str)。如果 given_time 已经是格式正确的字符串,那么您可以直接比较字符串,而无需先将它们转换为 datetime