Skip to content

Instantly share code, notes, and snippets.

@codymoorhouse
Last active August 23, 2018 17:40
Show Gist options
  • Save codymoorhouse/4acce9133664f7fdeb8625a060bae68c to your computer and use it in GitHub Desktop.
Save codymoorhouse/4acce9133664f7fdeb8625a060bae68c to your computer and use it in GitHub Desktop.
Creates a digital ocean snapshot
#!/usr/bin/python
#################################################################################
# Default Options #
#################################################################################
DEFAULT_NAME = "Snapshot - " + str(datetime.now().now())
DEFAULT_ALLOWED_SNAPSHOTS = 7
DEFAULT_DATA_CONSISTENCY_MODE = False
#################################################################################
# Executing / Args #
#################################################################################
# python3 do-snapshot.py -d droplet_id -t token #
# #
# Defaults: #
# -d, --droplet-id=droplet_id #
# The droplet id from digital ocean. In the digital ocean UI, click on #
# a droplet and the droplet id will be in the URL. #
# -t, --token=token #
# The access token from digital ocean. This is generated in the #
# digital ocean UI through the API settings. #
# #
# Optionals: #
# -a, --allowed-snapshots=max_allowed_snapshots #
# This will lock the amount of snapshots, removing the old extras. #
# -c, --consistency-mode #
# Powers off droplet before creating snapshot. #
# -h, --help #
# Print a help message and exit. #
# -n, --name=name #
# Specify the name of the snapshot to save as. #
#################################################################################
#################################################################################
# DO NOT TOUCH #
#################################################################################
import getopt
import json
import sys
import requests
import time
from datetime import datetime
def main(argv):
global ACCESS_TOKEN, BASE_URL, DROPLET_ID, DROPLET_NAME, HEADERS, ACTION_URL, ALLOWED_SNAPSHOTS, DATA_CONSISTENCY_MODE
validate_getopts(argv);
BASE_URL = "https://api.digitalocean.com/v2"
HEADERS = {
"Content-Type": "application/json",
"Authorization": "Bearer " + ACCESS_TOKEN
}
ACTION_URL = BASE_URL + '/droplets/' + DROPLET_ID + '/actions'
if (DATA_CONSISTENCY_MODE):
set_power("power_off")
create_action_info = create_snapshot(DROPLET_NAME)
action_info = get_action(create_action_info["action"]["id"])
while (action_info["action"]["status"] != "completed" and action_info["action"]["status"] != "errored"):
time.sleep(3)
action_info = get_action(create_action_info["action"]["id"])
if (action_info["action"]["status"] == "completed"):
print("Snapshot successfully created")
purge_snapshots(ALLOWED_SNAPSHOTS)
else:
print("Snapshot could not be created, an error has occurred")
if (DATA_CONSISTENCY_MODE):
set_power("power_on")
def purge_snapshots(amount):
response = get_snapshots();
if (response["meta"]["total"] > int(amount)):
snapshots = response["snapshots"]
purge_amount = response["meta"]["total"] - int(amount)
while (len(snapshots) > 0 and purge_amount > 0):
delete_snapshot(snapshots[0]["id"])
snapshots.pop(0)
if (len(snapshots) == 0 and purge_amount > 0):
response = get_snapshots();
snapshots = response["snapshots"]
purge_amount -= 1
return None
def create_snapshot(droplet_name):
data = {
"type": "snapshot",
"name": droplet_name
}
return requests.post(ACTION_URL, headers = HEADERS, json = data).json()
def delete_snapshot(snapshot_id):
return requests.delete(BASE_URL + '/snapshots/' + str(snapshot_id), headers = HEADERS)
def get_snapshots():
return requests.get(BASE_URL + '/droplets/' + DROPLET_ID + "/snapshots", headers = HEADERS).json()
def set_power(power_type):
data = { "type": power_type }
return requests.post(ACTION_URL, headers = HEADERS, json = data).json()
def get_action(action_id):
return requests.get(ACTION_URL + '/' + str(action_id), headers = HEADERS).json()
def validate_getopts(argv):
global ACCESS_TOKEN, DROPLET_ID, DROPLET_NAME, ALLOWED_SNAPSHOTS, DATA_CONSISTENCY_MODE
try:
short_args = "a:cd:ht:n:"
long_args = [ "allowed-snapshots=", "consistency-mode" "droplet-id=", "help", "token=", "name=" ]
opts, args = getopt.getopt(argv, short_args, long_args)
except getopt.GetoptError:
usage()
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit()
elif opt in ("-a", "--allowed-snapshots"):
ALLOWED_SNAPSHOTS = arg
elif opt in ("-c", "--consistency-mode"):
DATA_CONSISTENCY_MODE = True
elif opt in ("-d", "--droplet-id"):
DROPLET_ID = arg
elif opt in ("-t", "--token"):
ACCESS_TOKEN = arg
elif opt in ("-n", "--name"):
DROPLET_NAME = arg
############
# Required #
############
try:
ACCESS_TOKEN
except:
usage()
sys.exit(2)
try:
DROPLET_ID
except:
usage()
sys.exit(2)
################
# Not Required #
################
try:
DROPLET_NAME
except:
DROPLET_NAME = DEFAULT_NAME
try:
ALLOWED_SNAPSHOTS
except:
ALLOWED_SNAPSHOTS = DEFAULT_ALLOWED_SNAPSHOTS
try:
DATA_CONSISTENCY_MODE
except:
DATA_CONSISTENCY_MODE = DEFAULT_DATA_CONSISTENCY_MODE
def usage():
print("do-snapshot.py -d <droplet_id> -t <access_token> [-n <name>] [-a <allowed_snapshots>] [-c <consisteny_mode>] [-h]")
if __name__ == "__main__":
main(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment