(已失效)Vultr免费backup功能,如何实现自动定时快照?

目录
Vultr 的 backup 功能收费,但 snapshot 免费。本文使用 Python 调用 Vultr API 实现快照的自动创建和管理,配合 crontab 实现定时备份。
1 导读
- 有vultr的童鞋们想必都知道,backup和snapshot两者之间的区别并不大,都能实现备份。
- backup唯一好处就是自动备份,不需要像snapshot一样每次都手动创建。
- 有没有办法实现snapshot也自动化呢? 毕竟免费啊免费啊。答案是肯定的,请看作者的表演
2 预备知识
- 熟悉一门开发语言(作者用Python进行演示)
- 查阅vultr官方api文档
3 开启API功能
登陆vultr管理界面,从右上角头像进入api界面,然后点击[enable]按钮,并开启允许所有的ipv4地址使用该api key
4 编写各项功能的请求类
- 仔细观察api的url可以发现一定的规律
- 例如显示快照列表:/v1/snapshot/list
- 例如创建sshkey:/v1/sshkey/create
- 那么我们可以编写一个特殊的类来实现所有api的功能,不需要每个api都编写函数。使用的效果类似于:
- vultr = Vultr(‘api_key’)
- status_code, resp = vultr.snapshot.list()
- 主要是用了__getattr__和eval的特性,具体请看源码。(部分源码参考自互联网,修复了部分bug)
import requests
from requests import get
import re
class __RPC:
def __init__(self, api_key, name):
self.api_key = api_key
self.api_info = None
self.name = name
self.errors = {
200: "Function successfully executed.",
400: "Invalid API location. Check the URL that you are using.",
403: "Invalid or missing API key. Check that your API key is present and matches your assigned key.",
405: "Invalid HTTP method. Check that the method (POST|GET) matches what the documentation indicates.",
412: "Request failed. Check the response body for a more detailed description.",
500: "Internal server error. Try again at a later time.",
503: "Rate limit hit. API requests are limited to an average of 2/s. Try your request again later."
}
def api_info_initial(self):
res = get("https://www.vultr.com/api/")
html = res.text
methods = (m.group(1) for m in re.finditer(r"<td>(POST|GET)</td>", html))
names = (m.group(1) for m in re.finditer(r"/v1/(.*?)</a>", html))
self.api_info = dict(zip(names, methods))
def __getattr__(self, name):
return eval("__RPC")(self.api_key, self.name + "/" + name)
def __call__(self, **kwargs):
if not self.api_info:
self.api_info_initial()
if self.name not in self.api_info:
raise ValueError("The API is not exists.")
if self.api_info[self.name] == "GET":
res = requests.get("https://api.vultr.com/v1/" + self.name, headers={"API-Key": self.api_key},
params=kwargs)
elif self.api_info[self.name] == "POST":
res = requests.post("https://api.vultr.com/v1/" + self.name, headers={"API-Key": self.api_key}, data=kwargs)
if res.status_code == 200:
return res.status_code, res.text.strip()
elif res.status_code in self.errors.keys():
return res.status_code, self.errors.get(res.status_code)
else:
res.raise_for_status()
class Vultr:
def __init__(self, api_key):
self.api_key = api_key
def __getattr__(self, name):
return eval("__RPC")(self.api_key, name)
5 快照请求
发起创建快照请求,并删除超过3010个之后的快照,防止快照太多了造成vultr资源滥用,毕竟免费用的啊
注意
更新:只能创建10个快照
- 先获取到创建的vps对应的SUBID:/v1/server/list
from vultr import Vultr
vultr = Vultr("api_key")
status_code, resp = vultr.server.list()
print(status_code, resp)
# print的响应
# 200 {'15388455': {'SUBID': '15388455', ......}}
- 发起创建快照请求:/v1/snapshot/create。如果状态是200,表示创建成功,去网页上看看果然创建了。需要注意的是当一个快照处于pending状态时,服务被锁定,如果再创建快照,报412错误。也就是说不能同时创建多个快照。
from vultr import Vultr
vultr = Vultr("api_key")
data = {'SUBID': '15388455'}
status_code, resp = vultr.snapshot.create(**data)
print(status_code, resp)
# print的响应
# 200 {'SNAPSHOTID': '1e05b17c45fd6'}
- 删除超过30个之后的快照,根据时间排序
# 删除旧快照
status_code, resp = vultr.snapshot.list() # /v1/snapshot/list
if status_code != 200:
logger.error(u'获取快照列表失败' + str(status_code) + resp)
else:
logger.info(u'成功获取到快照列表')
data_list = list(json.loads(resp).values())
data_list.sort(key=lambda x: x['date_created']) # 默认时间排序,由近到远
data_list_del = data_list[10:] # 取超过30个之后的快照
for data_del in data_list_del:
data = {'SNAPSHOTID': data_del.get('SNAPSHOTID')}
status_code, resp = vultr.snapshot.destroy(**data) # /v1/snapshot/destroy
if status_code != 200:
logger.error(u'删除旧快照失败')
else:
logger.info(u'成功删除一个旧快照')
6 添加crontab定时任务
# 自动创建快照
30 18 * * * /usr/bin/python3 /home/script/vultr-snapshot.py
7 思维拓展
当创建快照失败的时候,如果能有一封邮件提醒岂不是更高潮嘛,嗯,简单,logging已经提供了邮件发送功能,照着写配置就ok啦!
8 总结
虽然说快照功能是免费,但是扛不住人多呀。所以,源码就不提供了,关键部分文中都已经给出了。如果真的想要源码学习交流呢,请发邮件给我