Skip to content

Commit aa5b4a5

Browse files
authored
Merge pull request #4 from TechConsult/imports_and_documentation
Imports and documentation
2 parents b114e05 + cdf02e7 commit aa5b4a5

14 files changed

+248
-40
lines changed

README.md

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,6 @@ python setup.py install
5050
* Manage firewall (on/off and individual rules)
5151
* since 0.2: full management of firewall rules
5252

53-
**TODO:**
54-
* Cloning of storages
55-
* Full management of special storage types:
56-
* CDROMs, custom OS templates
57-
* (custom templates can already be cloned to a disk via UUID)
58-
* Full management of backups (instant and scheduled)
59-
6053
**Changelog:**
6154
* See the [Releases page](https://github.com/UpCloudLtd/upcloud-python-api/releases)
6255

docs/storage-mixin.md

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,68 @@ def detach_storage(self, server_uuid, address):
6262
"""
6363
Detach a Storage object to a Server. Return a list of the server's storages.
6464
"""
65-
```
65+
```
66+
67+
```python
68+
def load_cd_rom(self, server, address):
69+
"""
70+
Loads a storage as a CD-ROM in the CD-ROM device of a server. Returns a list of the server's storages.
71+
"""
72+
```
73+
74+
```python
75+
def eject_cd_rom(self, server):
76+
"""
77+
Ejects the storage from the CD-ROM device of a server. Returns a list of the server's storages.
78+
"""
79+
```
80+
81+
```python
82+
def create_storage_backup(self, storage, title):
83+
"""
84+
Creates a point-in-time backup of a storage resource. Returns a storage object.
85+
"""
86+
```
87+
88+
```python
89+
def restore_storage_backup(self, storage):
90+
"""
91+
Restores the origin storage with data from the specified backup storage. Returns a storage object.
92+
"""
93+
```
94+
95+
```python
96+
def templatize_storage(self, storage, title):
97+
"""
98+
Creates an exact copy of an existing storage resource which can be used as a template for creating new servers. Returns a storage object.
99+
"""
100+
```
101+
102+
```python
103+
def create_storage_import(self, storage, source, source_location=None):
104+
"""
105+
Creates an import task to import data into an existing storage and returns a storage import object.
106+
Source types: http_import or direct_upload.
107+
"""
108+
```
109+
110+
```python
111+
def upload_file_for_storage_import(self, storage_import, file):
112+
"""
113+
Uploads a file directly to UpCloud's uploader session. Returns written bytes, md5sum and sha256sum.
114+
"""
115+
```
116+
117+
```python
118+
def get_storage_import_details(self, storage):
119+
"""
120+
Returns detailed information of an ongoing or finished import task within a storage import object.
121+
"""
122+
```
123+
124+
```python
125+
def cancel_storage_import(self, storage):
126+
"""
127+
Cancels an ongoing import task. Returns a storage import object.
128+
"""
129+
```

test/conftest.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,14 @@ def callback(request):
7878
content_type='application/json')
7979

8080
@staticmethod
81-
def mock_put(target):
81+
def mock_put(target, ignore_data_field=False, empty_payload=False, call_api=True):
8282
data = json.loads(Mock.read_from_file(target + '.json'))
8383

8484
def callback(request):
85-
return Mock.__put_post_callback(request, target, data)
85+
return Mock.__put_post_callback(request, target, data, ignore_data_field, empty_payload)
8686

87-
responses.add_callback(responses.PUT, Mock.base_url + '/' + target,
87+
url = Mock.base_url + '/' + target if call_api else target
88+
responses.add_callback(responses.PUT, url,
8889
callback=callback,
8990
content_type='application/json')
9091

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"written_bytes":909500125,"md5sum":"5cc6f7e7a1c52303ac3137d62410eec5","sha256sum":"bdf14d897406939c11a73d0720ca75c709e756d437f8be9ee26af6b58ede3bd7"}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"storage_import": {
3+
"client_content_length": 0,
4+
"client_content_type": "",
5+
"completed": "",
6+
"created": "2020-06-26T08:51:07Z",
7+
"error_code": "",
8+
"error_message": "",
9+
"md5sum": "",
10+
"read_bytes": 0,
11+
"sha256sum": "",
12+
"source": "http_import",
13+
"source_location": "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-10.4.0-amd64-netinst.iso",
14+
"state": "pending",
15+
"uuid": "07a6c9a3-300e-4d0e-b935-624f3dbdff3f",
16+
"written_bytes": 0
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"storage_import": {
3+
"client_content_length": 0,
4+
"client_content_type": "",
5+
"completed": "",
6+
"created": "2020-06-26T08:51:07Z",
7+
"error_code": "",
8+
"error_message": "",
9+
"md5sum": "",
10+
"read_bytes": 0,
11+
"sha256sum": "",
12+
"source": "http_import",
13+
"source_location": "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-10.4.0-amd64-netinst.iso",
14+
"state": "cancelling",
15+
"uuid": "07a6c9a3-300e-4d0e-b935-624f3dbdff3f",
16+
"written_bytes": 0
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"storage_import": {
3+
"client_content_length": 0,
4+
"client_content_type": "",
5+
"completed": "",
6+
"created": "2020-06-26T08:51:07Z",
7+
"direct_upload_url": "https://fi-hel1.img.upcloud.com/uploader/session/07a6c9a3-300e-4d0e-b935-624f3dbdff3f",
8+
"error_code": "",
9+
"error_message": "",
10+
"md5sum": "",
11+
"read_bytes": 0,
12+
"sha256sum": "",
13+
"source": "direct_upload",
14+
"state": "prepared",
15+
"uuid": "07a6c9a3-300e-4d0e-b935-624f3dbdff3f",
16+
"written_bytes": 0
17+
}
18+
}

test/json_data/test_file.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
test file for upload test

test/test_storage.py

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,35 @@ def test_templatize_storage(self, manager):
9393
assert storage.type == "template"
9494

9595
@responses.activate
96-
def test_add_storage_to_favorites(self, manager):
97-
data = Mock.mock_post("storage/01d4fcd4-e446-433b-8a9c-551a1284952e/favorite", empty_content=True)
98-
res = manager.add_storage_to_favorites("01d4fcd4-e446-433b-8a9c-551a1284952e")
99-
assert res == {}
100-
101-
@responses.activate
102-
def test_remove_storage_from_favorites(self, manager):
103-
data = Mock.mock_delete("storage/01d4fcd4-e446-433b-8a9c-551a1284952e/favorite")
104-
res = manager.remove_storage_from_favorites("01d4fcd4-e446-433b-8a9c-551a1284952e")
105-
assert res == {}
96+
def test_create_storage_import(self, manager):
97+
data = Mock.mock_post("storage/01d4fcd4-e446-433b-8a9c-551a1284952e/import", ignore_data_field=True)
98+
storage_import = manager.create_storage_import("01d4fcd4-e446-433b-8a9c-551a1284952e", 'direct_upload')
99+
assert storage_import.state == "prepared"
100+
assert storage_import.source == "direct_upload"
101+
102+
@responses.activate
103+
def test_upload_file_for_storage_import(self, manager):
104+
data = Mock.mock_post("storage/01d4fcd4-e446-433b-8a9c-551a1284952e/import", ignore_data_field=True)
105+
storage_import = manager.create_storage_import("01d4fcd4-e446-433b-8a9c-551a1284952e", 'direct_upload')
106+
data = Mock.mock_put("https://fi-hel1.img.upcloud.com/uploader/session/07a6c9a3-300e-4d0e-b935-624f3dbdff3f", ignore_data_field=True, empty_payload=True, call_api=False)
107+
res = manager.upload_file_for_storage_import(storage_import, 'test/json_data/test_file.json')
108+
assert res.get("written_bytes") == 909500125
109+
assert res.get("md5sum") == "5cc6f7e7a1c52303ac3137d62410eec5"
110+
assert res.get("sha256sum") == "bdf14d897406939c11a73d0720ca75c709e756d437f8be9ee26af6b58ede3bd7"
111+
112+
@responses.activate
113+
def test_get_storage_import_details(self, manager):
114+
data = Mock.mock_get("storage/01d4fcd4-e446-433b-8a9c-551a1284952e/import")
115+
storage_import = manager.get_storage_import_details("01d4fcd4-e446-433b-8a9c-551a1284952e")
116+
assert storage_import.state == "pending"
117+
assert storage_import.uuid == "07a6c9a3-300e-4d0e-b935-624f3dbdff3f"
118+
119+
@responses.activate
120+
def test_cancel_storage_import(self, manager):
121+
data = Mock.mock_post("storage/01d4fcd4-e446-433b-8a9c-551a1284952e/import/cancel", empty_payload=True, ignore_data_field=True)
122+
storage_import = manager.cancel_storage_import("01d4fcd4-e446-433b-8a9c-551a1284952e")
123+
assert storage_import.state == "cancelling"
124+
assert storage_import.uuid == "07a6c9a3-300e-4d0e-b935-624f3dbdff3f"
106125

107126
@responses.activate
108127
def test_storage_update(self, manager):

upcloud_api/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from upcloud_api.errors import UpCloudClientError, UpCloudAPIError
1818
from upcloud_api.constants import OperatingSystems, ZONE
1919
from upcloud_api.storage import Storage
20+
from upcloud_api.storage_import import StorageImport
2021
from upcloud_api.ip_address import IPAddress
2122
from upcloud_api.server import Server, login_user_block
2223
from upcloud_api.firewall import FirewallRule

0 commit comments

Comments
 (0)