-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpbsnappy.py
executable file
·117 lines (88 loc) · 4.44 KB
/
pbsnappy.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python
#
# pbsnappy - automatically make volume snapshots for ProfitBricks server
# Copyright (C) 2016 Gerben Meijer
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#
#
from datetime import datetime, timedelta
import config
from slugify import slugify
from pprint import pprint
from profitbricks.client import ProfitBricksService
client = ProfitBricksService( username=config.PB_USERNAME, password=config.PB_PASSWORD)
# Get the PB Datacenter object
datacenter = client.get_datacenter(datacenter_id=config.DATACENTER_ID)
# Get a list of snapshots; this is global so can be done here
snapshots = client.list_snapshots()
# Process all found entities (servers) in
for entity in datacenter['entities']['servers']['items']:
# If this entity is not a server, continue (could be gateway, loadbalancer etc)
if not entity['type'] == 'server':
continue
# Get this entitys server object from API
server = client.get_server(datacenter_id=config.DATACENTER_ID,server_id=entity['id'])
# Set the servername
servername = server['properties']['name']
# If this server is listed in our config, do the work
if servername in config.TARGET_SERVER_NAMES:
# Get the list of volumes for this server
for server_volume in server['entities']['volumes']['items']:
# Set volumeid
volumeid = server_volume['id']
# Get the volume object from API
volume = client.get_volume( datacenter_id=config.DATACENTER_ID,volume_id=volumeid)
# Set the volumename
volumename = volume['properties']['name']
# Assume we have no recent snapshots
no_recent_snapshot = True
# find snapshots that have a name starting with this volumename
for snapshot in snapshots['items']:
# Set the snapid and snapname
snapid = snapshot['id']
snapname = snapshot['properties']['name']
# Convert the snapshot createdDate to snapdate datetime object
snapdate = datetime.strptime(snapshot['metadata']['createdDate'], "%Y-%m-%dT%H:%M:%SZ")
# Check that the snapshot name starts with the target server name
# We do this in a for loop because we have to check string startswith()
if(snapname.startswith(volumename)):
# We have a match on snapshot name related to this volumename
snapage = datetime.utcnow() - snapdate
# Check if it's outdated and ready for deletion
if snapage > timedelta(days=config.RETENTION_DAYS):
# Too old, delete it
client.delete_snapshot(snapshot_id=snapid)
print "Server '%s' snapshot '%s' deleted, older than %d retention days (%d days, %d seconds)" % (servername, snapname, config.RETENTION_DAYS, snapage.days, snapage.seconds)
else:
# Recent, keep it
print "Server '%s' snapshot '%s' kept, not older than %d retention days (%d days, %d seconds)" % (servername, snapname, config.RETENTION_DAYS, snapage.days, snapage.seconds)
# For recent backups, check if it's less than min_snap_hours
if snapage < timedelta(hours=config.MIN_SNAP_HOURS):
# Snapshot is recent, don't make a new one
no_recent_snapshot = False
# Does this volume have recent snapshots?
if no_recent_snapshot:
# nothing recent, create one. Following PB default name syntax, e.g. "{volumename}-Snapshot-MM/DD/YYYY"
snapname = volumename + '-Snapshot-' + datetime.utcnow().strftime('%m/%d/%Y')
# Do the actual snapshot creation api call
newsnapshot = client.create_snapshot(datacenter_id=config.DATACENTER_ID,volume_id=volumeid, name=snapname)
print "Created new snapshot '%s' with id '%s'" % (snapname, newsnapshot['id'])
else:
# No need to make a snapshot, we have a recent one
print "Found snapshot less than %d hours old, not making new one" % config.MIN_SNAP_HOURS
else:
# This server is not managed based on config settings
print "Not managing snapshots for %s" % servername