Skip to content

Commit 257e026

Browse files
authored
Merge pull request #109 from UpCloudLtd/feat/storage-and-backup-deletion
Storage deletion & backup deletion policies
2 parents b6f58df + 1155578 commit 257e026

File tree

8 files changed

+105
-23
lines changed

8 files changed

+105
-23
lines changed

CHANGELOG.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
## [Unreleased]
1111

12+
### Added
13+
- Server deletion now support deleting attached storages in CloudManager.
14+
- Backup deletion policies can be given when deleting servers and storages.
15+
16+
----
17+
1218
## [2.0.0] - 2021-05-05
1319

1420
Python 2 is no longer supported. This is a maintenance release without
@@ -90,7 +96,7 @@ Template updates.
9096

9197
----
9298

93-
## [0.4.2] - 22 Feb 2018
99+
## [0.4.2] - 22 Feb 2018
94100

95101
- Added missing zones and missing templates.
96102
- Also removed old template windows 2008, which is not supported any more.
@@ -248,7 +254,7 @@ Major update with new features related to UpCloud's API v1.2
248254
Move to X.Y.Z versioning and bump version from 0.1(.0) to 0.1.1
249255

250256
- minor enchancement: Storage OS param can now take a UUID of a OS template. Useful if using custom OS templates.
251-
- bugfix: add cloud_manager to Server object during create_server.
257+
- bugfix: add cloud_manager to Server object during create_server.
252258
- added MANIFEST.in, tox.in, setup.cfg and removed docs/html from git (built by mkdocs from md sources)
253259
- sublime project file and some readme.md improvements
254260

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,21 @@ server.stop_and_destroy()
145145
server.ensure_started()
146146
```
147147

148+
CloudManager offers mode fine-grained deletion options for servers as you can choose to delete storages and
149+
choose what happens to their backups when deleting the server. By default the storage and their backups are
150+
always preserved.
151+
152+
Following example would delete all storages attached to a server, but would keep the latest backup
153+
of each storage if backups exist.
154+
155+
```python
156+
157+
from upcloud_api.storage import BackupDeletionPolicy
158+
159+
manager.delete_server(uuid, delete_storages=True, backups=BackupDeletionPolicy.KEEP_LATEST)
160+
161+
```
162+
148163
### Upgrade a Server
149164

150165
```python

docs/Server.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ server.remove_ip(IP)
114114

115115
```
116116

117-
## Destroy
117+
## Delete
118118

119119
Destroys the Server instance and its IP addresses. However, it does not destroy the Storages.
120120

@@ -123,3 +123,21 @@ Destroys the Server instance and its IP addresses. However, it does not destroy
123123
server.destroy()
124124

125125
```
126+
127+
## Delete with storages
128+
129+
Storages attached to the server and storage backups can also be deleted when deleting the server through CloudManager.
130+
Backups can be deleted only when attached storages are also deleted. Default policy for backup deletions is
131+
`KEEP`, but `KEEP_LATEST` and `DELETE` are also supported. Options are configured through BackupDeletionPolicy enum
132+
under storage. Default behaviour for backups and storages is always to keep them.
133+
134+
Following example deletes the storages, but keeps the latest existing backup(s). If no backup exists for the storage(s),
135+
nothing is left behind.
136+
137+
```python
138+
139+
from upcloud_api.storage import BackupDeletionPolicy
140+
141+
manager.delete_server(uuid, delete_storages=True, backups=BackupDeletionPolicy.KEEP_LATEST)
142+
143+
```

docs/Storage.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ storage.update(size=100, title="new title")
7171

7272
```
7373

74-
## Destroy
74+
## Delete
7575

7676
Warning: data loss is permanent.
7777

@@ -81,6 +81,23 @@ storage.destroy()
8181

8282
```
8383

84+
## Delete with backups
85+
86+
Backup deletion policy can be specified when deleting a storage through CloudManager. Default policy is
87+
`KEEP`, so no backups are deleted, but `KEEP_LATEST` and `DELETE` are also supported. Options are configured
88+
through BackupDeletionPolicy enum under storage. Default behaviour for backups is always to keep them.
89+
90+
Following example deletes the storage, but keeps the latest existing backup. If no backup exists for the storage,
91+
nothing is left behind.
92+
93+
```python
94+
95+
from upcloud_api.storage import BackupDeletionPolicy
96+
97+
manager.delete_storage(uuid, backups=BackupDeletionPolicy.KEEP_LATEST)
98+
99+
```
100+
84101
## Import
85102

86103
Storages can be imported either by passing a URL or by uploading the file. Currently .iso, .raw and .img formats

docs/storage-mixin.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ manager = CloudManager("api-username", "password")
1212
manager.method()
1313
```
1414

15+
`BackupDeletionPolicy` describes wanted action on backups when deleting a storage or a server with its storages.
16+
Available policies are `KEEP`, `KEEP_LATEST` and `DELETE`.
17+
1518
## Methods
1619

1720
```python

upcloud_api/cloud_manager/server_mixin.py

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
from upcloud_api.api import API
22
from upcloud_api.ip_address import IPAddress
33
from upcloud_api.server import Server
4-
from upcloud_api.storage import Storage
4+
from upcloud_api.storage import BackupDeletionPolicy, Storage
55

66

77
class ServerManager:
88
"""
9-
Functions for managing IP-addresses. Intended to be used as a mixin for CloudManager.
9+
Functions for managing servers. Intended to be used as a mixin for CloudManager.
1010
"""
1111

1212
api: API
@@ -32,13 +32,13 @@ def get_servers(self, populate=False, tags_has_one=None, tags_has_all=None):
3232
request = '/server'
3333
if tags_has_all:
3434
tags_has_all = [str(tag) for tag in tags_has_all]
35-
taglist = ':'.join(tags_has_all)
36-
request = f'/server/tag/{taglist}'
35+
tag_list = ':'.join(tags_has_all)
36+
request = f'/server/tag/{tag_list}'
3737

3838
if tags_has_one:
3939
tags_has_one = [str(tag) for tag in tags_has_one]
40-
taglist = ','.join(tags_has_one)
41-
request = f'/server/tag/{taglist}'
40+
tag_list = ','.join(tags_has_one)
41+
request = f'/server/tag/{tag_list}'
4242

4343
servers = self.api.get_request(request)['servers']['server']
4444

@@ -52,21 +52,21 @@ def get_servers(self, populate=False, tags_has_one=None, tags_has_all=None):
5252

5353
return server_list
5454

55-
def get_server(self, UUID: str) -> Server:
55+
def get_server(self, uuid: str) -> Server:
5656
"""
5757
Return a (populated) Server instance.
5858
"""
59-
server, IPAddresses, storages = self.get_server_data(UUID)
59+
server, ip_addresses, storages = self.get_server_data(uuid)
6060

6161
return Server(
6262
server,
63-
ip_addresses=IPAddresses,
63+
ip_addresses=ip_addresses,
6464
storage_devices=storages,
6565
populated=True,
6666
cloud_manager=self,
6767
)
6868

69-
def get_server_by_ip(self, ip_address):
69+
def get_server_by_ip(self, ip_address: str):
7070
"""
7171
Return a (populated) Server instance by its IP.
7272
@@ -152,23 +152,34 @@ def modify_server(self, uuid: str, **kwargs) -> Server:
152152
cloud_manager=self,
153153
)
154154

155-
def delete_server(self, uuid):
155+
def delete_server(
156+
self,
157+
uuid: str,
158+
delete_storages: bool = False,
159+
backups: BackupDeletionPolicy = BackupDeletionPolicy.KEEP,
160+
):
156161
"""
157162
DELETE '/server/UUID'. Permanently destroys the virtual machine.
158163
159-
DOES NOT remove the storage disks.
164+
Does remove storage disks if delete_storages is defined as True.
165+
166+
Does remove backups of the attached storages if
160167
161168
Returns an empty object.
162169
"""
163-
return self.api.delete_request(f'/server/{uuid}')
170+
storages = '1' if delete_storages else '0'
171+
172+
return self.api.delete_request(
173+
f'/server/{uuid}?storages={storages}&backups={backups.value}'
174+
)
164175

165-
def get_server_data(self, UUID):
176+
def get_server_data(self, uuid: str):
166177
"""
167178
Return '/server/uuid' data in Python dict.
168179
169180
Creates object representations of any IP-address and Storage.
170181
"""
171-
data = self.api.get_request(f'/server/{UUID}')
182+
data = self.api.get_request(f'/server/{uuid}')
172183
server = data['server']
173184

174185
# Populate subobjects

upcloud_api/cloud_manager/storage_mixin.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import BinaryIO, Optional, Union
33

44
from upcloud_api.api import API
5-
from upcloud_api.storage import Storage
5+
from upcloud_api.storage import BackupDeletionPolicy, Storage
66
from upcloud_api.storage_import import StorageImport
77

88

@@ -84,11 +84,11 @@ def modify_storage(
8484
res = self._modify_storage(str(storage), size, title, backup_rule)
8585
return Storage(cloud_manager=self, **res['storage'])
8686

87-
def delete_storage(self, UUID):
87+
def delete_storage(self, uuid: str, backups: BackupDeletionPolicy = BackupDeletionPolicy.KEEP):
8888
"""
89-
Destroy a Storage object.
89+
Destroy a Storage object, and possibly some or all of its backups.
9090
"""
91-
return self.api.delete_request('/storage/' + UUID)
91+
return self.api.delete_request(f'/storage/{uuid}?backups={backups.value}')
9292

9393
def clone_storage(
9494
self, storage: Union[Storage, str], title: str, zone: str, tier=None

upcloud_api/storage.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
1+
from enum import Enum
2+
13
from upcloud_api.upcloud_resource import UpCloudResource
24

35

6+
class BackupDeletionPolicy(Enum):
7+
"""
8+
Class representation of backup deletion policies used on storage deletions.
9+
"""
10+
11+
KEEP = 'keep'
12+
KEEP_LATEST = 'keep_latest'
13+
DELETE = 'delete'
14+
15+
416
class Storage(UpCloudResource):
517
"""
618
Class representation of UpCloud Storage instance.

0 commit comments

Comments
 (0)