mtn-cloud 0.2.16__tar.gz → 0.2.17__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/PKG-INFO +78 -3
  2. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/README.md +77 -2
  3. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/api-overview.md +15 -0
  4. mtn_cloud-0.2.17/docs/api-reference/backups.md +59 -0
  5. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/api-reference/index.md +3 -0
  6. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/api-reference/instances.md +32 -0
  7. mtn_cloud-0.2.17/docs/api-reference/security-groups.md +94 -0
  8. mtn_cloud-0.2.17/docs/api-reference/virtual-images.md +37 -0
  9. mtn_cloud-0.2.17/docs/backups.md +80 -0
  10. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/index.md +13 -7
  11. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/instances.md +27 -0
  12. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/networking.md +1 -1
  13. mtn_cloud-0.2.17/docs/security-groups.md +146 -0
  14. mtn_cloud-0.2.17/docs/virtual-images.md +65 -0
  15. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/_version.py +1 -1
  16. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/client.py +59 -0
  17. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/models/__init__.py +27 -0
  18. mtn_cloud-0.2.17/src/mtn_cloud/models/backup.py +93 -0
  19. mtn_cloud-0.2.17/src/mtn_cloud/models/security_group.py +195 -0
  20. mtn_cloud-0.2.17/src/mtn_cloud/models/snapshot.py +54 -0
  21. mtn_cloud-0.2.17/src/mtn_cloud/models/virtual_image.py +57 -0
  22. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/resources/__init__.py +8 -0
  23. mtn_cloud-0.2.17/src/mtn_cloud/resources/backups.py +173 -0
  24. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/resources/instances.py +77 -0
  25. mtn_cloud-0.2.17/src/mtn_cloud/resources/security_groups.py +350 -0
  26. mtn_cloud-0.2.17/src/mtn_cloud/resources/virtual_images.py +124 -0
  27. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/.gitignore +0 -0
  28. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/LICENSE +0 -0
  29. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/advanced-cookbook.md +0 -0
  30. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/api-reference/archive-buckets.md +0 -0
  31. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/api-reference/client.md +0 -0
  32. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/api-reference/clouds.md +0 -0
  33. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/api-reference/groups.md +0 -0
  34. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/api-reference/instance-types.md +0 -0
  35. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/api-reference/networks.md +0 -0
  36. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/api-reference/plans.md +0 -0
  37. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/api-reference/storage-buckets.md +0 -0
  38. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/docstring-style.md +0 -0
  39. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/quickstart.md +0 -0
  40. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/storage.md +0 -0
  41. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/docs/stylesheets/extra.css +0 -0
  42. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/pyproject.toml +0 -0
  43. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/__init__.py +0 -0
  44. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/config.py +0 -0
  45. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/exceptions.py +0 -0
  46. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/http.py +0 -0
  47. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/models/archive.py +0 -0
  48. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/models/base.py +0 -0
  49. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/models/cloud.py +0 -0
  50. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/models/group.py +0 -0
  51. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/models/instance.py +0 -0
  52. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/models/instance_type.py +0 -0
  53. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/models/network.py +0 -0
  54. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/models/plan.py +0 -0
  55. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/models/storage_bucket.py +0 -0
  56. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/models/user.py +0 -0
  57. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/models/volume.py +0 -0
  58. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/resources/archive_buckets.py +0 -0
  59. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/resources/base.py +0 -0
  60. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/resources/clouds.py +0 -0
  61. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/resources/groups.py +0 -0
  62. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/resources/instance_types.py +0 -0
  63. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/resources/networks.py +0 -0
  64. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/resources/plans.py +0 -0
  65. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/src/mtn_cloud/resources/storage_buckets.py +0 -0
  66. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/tests/__init__.py +0 -0
  67. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/tests/conftest.py +0 -0
  68. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/tests/test_archive_buckets.py +0 -0
  69. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/tests/test_client.py +0 -0
  70. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/tests/test_clouds.py +0 -0
  71. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/tests/test_config.py +0 -0
  72. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/tests/test_exceptions.py +0 -0
  73. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/tests/test_instance_types.py +0 -0
  74. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/tests/test_instances.py +0 -0
  75. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/tests/test_networks.py +0 -0
  76. {mtn_cloud-0.2.16 → mtn_cloud-0.2.17}/tests/test_storage_buckets.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mtn-cloud
3
- Version: 0.2.16
3
+ Version: 0.2.17
4
4
  Summary: Community Python SDK for MTN Cloud - Deploy and manage cloud resources with ease
5
5
  Project-URL: Homepage, https://github.com/mahveotm/mtn-cloud-python
6
6
  Project-URL: Documentation, https://github.com/mahveotm/mtn-cloud-python#readme
@@ -50,7 +50,7 @@ Description-Content-Type: text/markdown
50
50
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
51
51
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
52
52
 
53
- A Modern Python SDK for [MTN Cloud](https://console.cloud.mtn.ng) with typed models, clear resource managers, and practical workflows for compute, networking, storage, and archives.
53
+ A Modern Python SDK for [MTN Cloud](https://console.cloud.mtn.ng) with typed models, clear resource managers, and practical workflows for compute, networking, storage, archives, security groups, backups, and more.
54
54
 
55
55
  Docs: [mtn-cloud-python](https://mahveotm.github.io/mtn-cloud-python/)
56
56
 
@@ -78,6 +78,9 @@ pip install mtn-cloud
78
78
  - [Instances](https://mahveotm.github.io/mtn-cloud-python/instances/)
79
79
  - [Networking](https://mahveotm.github.io/mtn-cloud-python/networking/)
80
80
  - [Storage](https://mahveotm.github.io/mtn-cloud-python/storage/)
81
+ - [Security Groups](https://mahveotm.github.io/mtn-cloud-python/security-groups/)
82
+ - [Backups](https://mahveotm.github.io/mtn-cloud-python/backups/)
83
+ - [Virtual Images](https://mahveotm.github.io/mtn-cloud-python/virtual-images/)
81
84
  - [Advanced Cookbook](https://mahveotm.github.io/mtn-cloud-python/advanced-cookbook/)
82
85
  - [API Overview](https://mahveotm.github.io/mtn-cloud-python/api-overview/)
83
86
  - [API Reference](https://mahveotm.github.io/mtn-cloud-python/api-reference/)
@@ -200,7 +203,79 @@ subnets = cloud.networks.list_subnets(new_network.id)
200
203
  print(f"Subnets: {len(subnets)}")
201
204
  ```
202
205
 
203
- ### 5. Work with Storage and Archives
206
+ ### 5. Manage Security Groups
207
+
208
+ ```python
209
+ # Create a security group and add rules
210
+ sg = cloud.security_groups.create(
211
+ name="web-servers",
212
+ description="HTTP, HTTPS, and SSH access",
213
+ )
214
+
215
+ cloud.security_groups.create_rule(
216
+ sg.id,
217
+ name="allow-ssh",
218
+ direction="ingress",
219
+ protocol="tcp",
220
+ port_range="22",
221
+ )
222
+
223
+ cloud.security_groups.create_rule(
224
+ sg.id,
225
+ name="allow-https",
226
+ direction="ingress",
227
+ protocol="tcp",
228
+ port_range="443",
229
+ )
230
+
231
+ # Use the security group when provisioning
232
+ instance = cloud.instances.create(
233
+ name="app-server-01",
234
+ cloud="MTNNG_CLOUD_AZ_1",
235
+ type="MTN-CS10",
236
+ group="MTNNG_CLOUD_AZ_1",
237
+ layout=327,
238
+ plan=6776,
239
+ resource_pool_id="pool-214",
240
+ security_group="web-servers",
241
+ )
242
+ ```
243
+
244
+ ### 6. Snapshot Instances
245
+
246
+ ```python
247
+ # Create a snapshot before a risky operation
248
+ snap = cloud.instances.create_snapshot(
249
+ instance_id=instance.id,
250
+ name="pre-upgrade",
251
+ )
252
+
253
+ # Revert if something goes wrong (stop the instance first)
254
+ cloud.instances.stop(instance.id)
255
+ cloud.instances.wait_until_stopped(instance.id)
256
+ cloud.instances.revert_snapshot(instance.id, snapshot_id=snap.id)
257
+ ```
258
+
259
+ ### 7. Work with Backups
260
+
261
+ ```python
262
+ # List configured backups and their status
263
+ for backup in cloud.backups.list():
264
+ print(f"{backup.name}: last_run={backup.last_run} status={backup.last_status}")
265
+
266
+ # Trigger an immediate backup run
267
+ cloud.backups.execute(backup_id=42)
268
+
269
+ # Check execution history
270
+ for result in cloud.backups.list_results(backup_id=42):
271
+ print(f"{result.start_date}: {result.status} ({result.size_in_mb} MB)")
272
+
273
+ # List and execute backup jobs (schedules)
274
+ for job in cloud.backups.list_jobs():
275
+ print(f"{job.name}: cron={job.cron_expression}")
276
+ ```
277
+
278
+ ### 8. Work with Storage and Archives
204
279
 
205
280
  ```python
206
281
  # Create S3-compatible storage provider
@@ -6,7 +6,7 @@
6
6
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
8
 
9
- A Modern Python SDK for [MTN Cloud](https://console.cloud.mtn.ng) with typed models, clear resource managers, and practical workflows for compute, networking, storage, and archives.
9
+ A Modern Python SDK for [MTN Cloud](https://console.cloud.mtn.ng) with typed models, clear resource managers, and practical workflows for compute, networking, storage, archives, security groups, backups, and more.
10
10
 
11
11
  Docs: [mtn-cloud-python](https://mahveotm.github.io/mtn-cloud-python/)
12
12
 
@@ -34,6 +34,9 @@ pip install mtn-cloud
34
34
  - [Instances](https://mahveotm.github.io/mtn-cloud-python/instances/)
35
35
  - [Networking](https://mahveotm.github.io/mtn-cloud-python/networking/)
36
36
  - [Storage](https://mahveotm.github.io/mtn-cloud-python/storage/)
37
+ - [Security Groups](https://mahveotm.github.io/mtn-cloud-python/security-groups/)
38
+ - [Backups](https://mahveotm.github.io/mtn-cloud-python/backups/)
39
+ - [Virtual Images](https://mahveotm.github.io/mtn-cloud-python/virtual-images/)
37
40
  - [Advanced Cookbook](https://mahveotm.github.io/mtn-cloud-python/advanced-cookbook/)
38
41
  - [API Overview](https://mahveotm.github.io/mtn-cloud-python/api-overview/)
39
42
  - [API Reference](https://mahveotm.github.io/mtn-cloud-python/api-reference/)
@@ -156,7 +159,79 @@ subnets = cloud.networks.list_subnets(new_network.id)
156
159
  print(f"Subnets: {len(subnets)}")
157
160
  ```
158
161
 
159
- ### 5. Work with Storage and Archives
162
+ ### 5. Manage Security Groups
163
+
164
+ ```python
165
+ # Create a security group and add rules
166
+ sg = cloud.security_groups.create(
167
+ name="web-servers",
168
+ description="HTTP, HTTPS, and SSH access",
169
+ )
170
+
171
+ cloud.security_groups.create_rule(
172
+ sg.id,
173
+ name="allow-ssh",
174
+ direction="ingress",
175
+ protocol="tcp",
176
+ port_range="22",
177
+ )
178
+
179
+ cloud.security_groups.create_rule(
180
+ sg.id,
181
+ name="allow-https",
182
+ direction="ingress",
183
+ protocol="tcp",
184
+ port_range="443",
185
+ )
186
+
187
+ # Use the security group when provisioning
188
+ instance = cloud.instances.create(
189
+ name="app-server-01",
190
+ cloud="MTNNG_CLOUD_AZ_1",
191
+ type="MTN-CS10",
192
+ group="MTNNG_CLOUD_AZ_1",
193
+ layout=327,
194
+ plan=6776,
195
+ resource_pool_id="pool-214",
196
+ security_group="web-servers",
197
+ )
198
+ ```
199
+
200
+ ### 6. Snapshot Instances
201
+
202
+ ```python
203
+ # Create a snapshot before a risky operation
204
+ snap = cloud.instances.create_snapshot(
205
+ instance_id=instance.id,
206
+ name="pre-upgrade",
207
+ )
208
+
209
+ # Revert if something goes wrong (stop the instance first)
210
+ cloud.instances.stop(instance.id)
211
+ cloud.instances.wait_until_stopped(instance.id)
212
+ cloud.instances.revert_snapshot(instance.id, snapshot_id=snap.id)
213
+ ```
214
+
215
+ ### 7. Work with Backups
216
+
217
+ ```python
218
+ # List configured backups and their status
219
+ for backup in cloud.backups.list():
220
+ print(f"{backup.name}: last_run={backup.last_run} status={backup.last_status}")
221
+
222
+ # Trigger an immediate backup run
223
+ cloud.backups.execute(backup_id=42)
224
+
225
+ # Check execution history
226
+ for result in cloud.backups.list_results(backup_id=42):
227
+ print(f"{result.start_date}: {result.status} ({result.size_in_mb} MB)")
228
+
229
+ # List and execute backup jobs (schedules)
230
+ for job in cloud.backups.list_jobs():
231
+ print(f"{job.name}: cron={job.cron_expression}")
232
+ ```
233
+
234
+ ### 8. Work with Storage and Archives
160
235
 
161
236
  ```python
162
237
  # Create S3-compatible storage provider
@@ -19,6 +19,9 @@ from mtn_cloud import MTNCloud
19
19
  - `plans`
20
20
  - `storage_buckets`
21
21
  - `archive_buckets`
22
+ - `security_groups`
23
+ - `backups`
24
+ - `virtual_images`
22
25
 
23
26
  ## Authentication Options
24
27
 
@@ -43,6 +46,9 @@ cloud.instances.create(...)
43
46
  cloud.instances.update(instance_id=123, name="new-name")
44
47
  cloud.instances.delete(123)
45
48
 
49
+ cloud.instances.create_snapshot(123, "pre-upgrade")
50
+ cloud.instances.revert_snapshot(123, snapshot_id=456)
51
+
46
52
  cloud.networks.create(...)
47
53
  cloud.networks.update(298, description="updated")
48
54
  cloud.networks.delete(298)
@@ -50,6 +56,11 @@ cloud.networks.delete(298)
50
56
  cloud.storage_buckets.create_s3(...)
51
57
  cloud.archive_buckets.create(...)
52
58
  cloud.archive_buckets.upload_file(...)
59
+
60
+ cloud.security_groups.create(name="web-servers")
61
+ cloud.security_groups.create_rule(sg_id, direction="ingress", protocol="tcp", port_range="22")
62
+
63
+ cloud.backups.execute(backup_id=42)
53
64
  ```
54
65
 
55
66
  ## Exception Hierarchy
@@ -80,6 +91,10 @@ Resource methods return typed Pydantic models, for example:
80
91
  - `StorageBucket`
81
92
  - `ArchiveBucket`
82
93
  - `ArchiveFile`
94
+ - `SecurityGroup`, `SecurityGroupRule`
95
+ - `Snapshot`
96
+ - `Backup`, `BackupJob`, `BackupResult`
97
+ - `VirtualImage`
83
98
 
84
99
  ## Naming Conventions
85
100
 
@@ -0,0 +1,59 @@
1
+ # Resource: `cloud.backups` (`BackupsResource`)
2
+
3
+ ### `list(max_results=None, offset=0, phrase=None, **filters) -> list[Backup]`
4
+
5
+ - Endpoint: `GET /api/backups`
6
+ - Parameters:
7
+ - Shared list args (see [API Reference](./index.md#shared-list-query-arguments))
8
+ - Returns: `list[Backup]`
9
+ - Raises: common API exceptions
10
+
11
+ ### `get(backup_id: int) -> Backup`
12
+
13
+ - Endpoint: `GET /api/backups/{backup_id}`
14
+ - Returns: `Backup`
15
+ - Raises: common API exceptions
16
+
17
+ ### `execute(backup_id: int) -> dict[str, Any]`
18
+
19
+ - Endpoint: `POST /api/backups/{backup_id}/execute`
20
+ - Triggers an immediate out-of-schedule backup run
21
+ - Returns: raw execution status response
22
+ - Raises: common API exceptions
23
+
24
+ ### `list_results(backup_id: int, max_results=None) -> list[BackupResult]`
25
+
26
+ - Endpoint: `GET /api/backups/{backup_id}/results`
27
+ - Parameters:
28
+ - `max_results`: maps to query `max`
29
+ - Returns: `list[BackupResult]` — each result carries `status`, `size_in_mb`, `duration_millis`, `start_date`, `end_date`
30
+ - Raises: common API exceptions
31
+
32
+ ### `delete(backup_id: int) -> bool`
33
+
34
+ - Endpoint: `DELETE /api/backups/{backup_id}`
35
+ - Returns: `True` on success
36
+ - Raises: common API exceptions
37
+
38
+ ---
39
+
40
+ ## Job management
41
+
42
+ ### `list_jobs(max_results=None, offset=0) -> list[BackupJob]`
43
+
44
+ - Endpoint: `GET /api/backups/jobs`
45
+ - Returns: `list[BackupJob]`
46
+ - Raises: common API exceptions
47
+
48
+ ### `get_job(job_id: int) -> BackupJob`
49
+
50
+ - Endpoint: `GET /api/backups/jobs/{job_id}`
51
+ - Returns: `BackupJob`
52
+ - Raises: common API exceptions
53
+
54
+ ### `execute_job(job_id: int) -> dict[str, Any]`
55
+
56
+ - Endpoint: `POST /api/backups/jobs/{job_id}/execute`
57
+ - Triggers an immediate run of all backups under the job
58
+ - Returns: raw execution status response
59
+ - Raises: common API exceptions
@@ -13,6 +13,9 @@ This section documents the public SDK surface in endpoint-first format.
13
13
  - [Plans (`cloud.plans`)](./plans.md)
14
14
  - [Storage Buckets (`cloud.storage_buckets`)](./storage-buckets.md)
15
15
  - [Archive Buckets (`cloud.archive_buckets`)](./archive-buckets.md)
16
+ - [Security Groups (`cloud.security_groups`)](./security-groups.md)
17
+ - [Backups (`cloud.backups`)](./backups.md)
18
+ - [Virtual Images (`cloud.virtual_images`)](./virtual-images.md)
16
19
 
17
20
  ## Conventions
18
21
 
@@ -165,3 +165,35 @@ Client-side polling helper.
165
165
  - `max_results`: maps to query `max`
166
166
  - Returns: list from response key `processes`
167
167
  - Raises: common API exceptions
168
+
169
+ ---
170
+
171
+ ## Snapshot management
172
+
173
+ ### `list_snapshots(instance_id: int) -> list[Snapshot]`
174
+
175
+ - Endpoint: `GET /api/instances/{instance_id}/snapshots`
176
+ - Returns: `list[Snapshot]`
177
+ - Raises: common API exceptions
178
+
179
+ ### `create_snapshot(instance_id: int, name: str, *, description=None) -> Snapshot`
180
+
181
+ - Endpoint: `POST /api/instances/{instance_id}/snapshots`
182
+ - Parameters:
183
+ - `name`: snapshot name
184
+ - `description`: optional description
185
+ - Returns: `Snapshot`
186
+ - Raises: common API exceptions
187
+
188
+ ### `revert_snapshot(instance_id: int, snapshot_id: int) -> bool`
189
+
190
+ - Endpoint: `PUT /api/instances/{instance_id}/revert-snapshot/{snapshot_id}`
191
+ - The instance should be stopped before reverting
192
+ - Returns: `True` when revert is initiated
193
+ - Raises: common API exceptions
194
+
195
+ ### `delete_snapshot(instance_id: int, snapshot_id: int) -> bool`
196
+
197
+ - Endpoint: `DELETE /api/instances/{instance_id}/snapshots/{snapshot_id}`
198
+ - Returns: `True` on success
199
+ - Raises: common API exceptions
@@ -0,0 +1,94 @@
1
+ # Resource: `cloud.security_groups` (`SecurityGroupsResource`)
2
+
3
+ ### `list(max_results=None, offset=0, phrase=None, name=None, **filters) -> list[SecurityGroup]`
4
+
5
+ - Endpoint: `GET /api/security-groups`
6
+ - Parameters:
7
+ - Shared list args (see [API Reference](./index.md#shared-list-query-arguments))
8
+ - `name`: filter by name
9
+ - Returns: `list[SecurityGroup]` — each includes its embedded `rules` list
10
+ - Raises: common API exceptions
11
+
12
+ ### `get(security_group_id: int) -> SecurityGroup`
13
+
14
+ - Endpoint: `GET /api/security-groups/{security_group_id}`
15
+ - Returns: `SecurityGroup` with all rules populated
16
+ - Raises: common API exceptions
17
+
18
+ ### `get_by_name(name: str) -> SecurityGroup`
19
+
20
+ - Endpoint sequence:
21
+ - `GET /api/security-groups?name=<name>&max=1`
22
+ - Parameters:
23
+ - `name`: security group name
24
+ - Returns: `SecurityGroup`
25
+ - Raises:
26
+ - common API exceptions
27
+ - `NotFoundError` when no group matches
28
+
29
+ ### `create(name: str, *, description=None) -> SecurityGroup`
30
+
31
+ - Endpoint: `POST /api/security-groups`
32
+ - Parameters:
33
+ - `name`: group name
34
+ - `description`: optional description
35
+ - Returns: created `SecurityGroup`
36
+ - Raises: common API exceptions
37
+
38
+ ### `update(security_group_id: int, *, name=None, description=None) -> SecurityGroup`
39
+
40
+ - Endpoint: `PUT /api/security-groups/{security_group_id}`
41
+ - Parameters:
42
+ - `name`: replacement name
43
+ - `description`: replacement description
44
+ - Returns: updated `SecurityGroup`
45
+ - Raises: common API exceptions
46
+
47
+ ### `delete(security_group_id: int) -> bool`
48
+
49
+ - Endpoint: `DELETE /api/security-groups/{security_group_id}`
50
+ - Returns: `True` on success
51
+ - Raises: common API exceptions
52
+
53
+ ---
54
+
55
+ ## Rule management
56
+
57
+ ### `list_rules(security_group_id: int) -> list[SecurityGroupRule]`
58
+
59
+ - Endpoint sequence:
60
+ - `GET /api/security-groups/{security_group_id}` (rules embedded in response)
61
+ - Returns: `list[SecurityGroupRule]`
62
+ - Raises: common API exceptions
63
+
64
+ ### `create_rule(security_group_id: int, *, name=None, direction="ingress", policy="accept", protocol=None, port_range=None, destination_port_range=None, source_type="all", source=None, destination_type="instance", destination=None, ethertype=None, priority=None, enabled=None) -> SecurityGroupRule`
65
+
66
+ - Endpoint: `POST /api/security-groups/{security_group_id}/rules`
67
+ - Parameters:
68
+ - `direction`: `"ingress"` or `"egress"`
69
+ - `policy`: `"accept"` or `"deny"`
70
+ - `protocol`: `"tcp"`, `"udp"`, `"icmp"`, or `"any"`
71
+ - `port_range`: source port or range, e.g. `"22"` or `"8000-9000"`
72
+ - `destination_port_range`: destination port or range
73
+ - `source_type`: `"cidr"`, `"group"`, `"instance"`, or `"all"`
74
+ - `source`: CIDR string (required when `source_type="cidr"`)
75
+ - `destination_type`: `"cidr"`, `"group"`, `"instance"`, or `"all"`
76
+ - `destination`: destination CIDR or reference
77
+ - `ethertype`: `"IPv4"` or `"IPv6"`
78
+ - `priority`: integer — lower value = higher priority
79
+ - `enabled`: whether rule is active
80
+ - Returns: `SecurityGroupRule`
81
+ - Raises: common API exceptions
82
+
83
+ ### `update_rule(security_group_id: int, rule_id: int, *, name=None, direction=None, policy=None, protocol=None, port_range=None, destination_port_range=None, source_type=None, source=None, destination_type=None, destination=None, ethertype=None, priority=None, enabled=None) -> SecurityGroupRule`
84
+
85
+ - Endpoint: `PUT /api/security-groups/{security_group_id}/rules/{rule_id}`
86
+ - Parameters: same as `create_rule`, all optional
87
+ - Returns: updated `SecurityGroupRule`
88
+ - Raises: common API exceptions
89
+
90
+ ### `delete_rule(security_group_id: int, rule_id: int) -> bool`
91
+
92
+ - Endpoint: `DELETE /api/security-groups/{security_group_id}/rules/{rule_id}`
93
+ - Returns: `True` on success
94
+ - Raises: common API exceptions
@@ -0,0 +1,37 @@
1
+ # Resource: `cloud.virtual_images` (`VirtualImagesResource`)
2
+
3
+ ### `list(max_results=None, offset=0, phrase=None, name=None, image_type=None, is_public=None, **filters) -> list[VirtualImage]`
4
+
5
+ - Endpoint: `GET /api/virtual-images`
6
+ - Parameters:
7
+ - Shared list args (see [API Reference](./index.md#shared-list-query-arguments))
8
+ - `name`: filter by name (exact)
9
+ - `image_type`: filter by image type string (e.g. `"vmware"`, `"qcow2"`)
10
+ - `is_public`: `True` maps to query `filterType=public`; `False` maps to `filterType=private`
11
+ - Returns: `list[VirtualImage]`
12
+ - Raises: common API exceptions
13
+
14
+ ### `get(virtual_image_id: int) -> VirtualImage`
15
+
16
+ - Endpoint: `GET /api/virtual-images/{virtual_image_id}`
17
+ - Returns: `VirtualImage`
18
+ - Raises: common API exceptions
19
+
20
+ ### `get_by_name(name: str) -> VirtualImage`
21
+
22
+ - Endpoint sequence:
23
+ - `GET /api/virtual-images?phrase=<name>&max=25`
24
+ - Linear scan of results for exact name match
25
+ - Parameters:
26
+ - `name`: exact image name
27
+ - Returns: `VirtualImage`
28
+ - Raises:
29
+ - common API exceptions
30
+ - `NotFoundError` when no image with that exact name is found
31
+
32
+ ### `delete(virtual_image_id: int) -> bool`
33
+
34
+ - Endpoint: `DELETE /api/virtual-images/{virtual_image_id}`
35
+ - Only custom (user-uploaded) images can be deleted; platform-provided images will return a 403
36
+ - Returns: `True` on success
37
+ - Raises: common API exceptions
@@ -0,0 +1,80 @@
1
+ # Backups
2
+
3
+ Use this guide to list, inspect, and trigger backup jobs via the SDK.
4
+
5
+ ## How Backups Work on MTN Cloud
6
+
7
+ Backups are configured and scheduled through the MTN Cloud Console under **Backups**. The SDK gives you read and execution access — you can list configured backups, inspect their last run status, retrieve execution results, and trigger an immediate run. Creating new backup configurations is done in the console.
8
+
9
+ Two distinct objects exist in the API:
10
+ - **Backup** — a configuration attached to a specific instance or server.
11
+ - **Backup Job** — a schedule (cron expression + retention policy) that groups one or more backups.
12
+
13
+ ## List Backups
14
+
15
+ ```python
16
+ from mtn_cloud import MTNCloud
17
+
18
+ cloud = MTNCloud(token="your-api-token")
19
+
20
+ backups = cloud.backups.list()
21
+ for b in backups:
22
+ print(f"{b.id} {b.name} last_run={b.last_run} status={b.last_status}")
23
+ ```
24
+
25
+ ## Get a Backup
26
+
27
+ ```python
28
+ backup = cloud.backups.get(42)
29
+ print(backup.name, backup.enabled, backup.retention_count)
30
+ ```
31
+
32
+ ## Execute a Backup Immediately
33
+
34
+ Triggers an out-of-schedule run. Useful before a major change.
35
+
36
+ ```python
37
+ result = cloud.backups.execute(backup_id=42)
38
+ print(result)
39
+ ```
40
+
41
+ ## Get Execution Results
42
+
43
+ Returns the history of runs for a specific backup — each with size, duration, and status.
44
+
45
+ ```python
46
+ results = cloud.backups.list_results(backup_id=42)
47
+ for r in results:
48
+ print(f" {r.start_date} status={r.status} size={r.size_in_mb} MB duration={r.duration_millis} ms")
49
+ ```
50
+
51
+ ## Backup Jobs
52
+
53
+ Backup jobs are the scheduling layer. A single job can cover multiple backups.
54
+
55
+ ```python
56
+ # List jobs
57
+ jobs = cloud.backups.list_jobs()
58
+ for job in jobs:
59
+ print(f"{job.id} {job.name} cron={job.cron_expression} last_status={job.last_status}")
60
+
61
+ # Get a specific job
62
+ job = cloud.backups.get_job(job_id=10)
63
+
64
+ # Execute a job immediately
65
+ cloud.backups.execute_job(job_id=10)
66
+ ```
67
+
68
+ ## Delete a Backup Configuration
69
+
70
+ Deletes the backup configuration but does not delete existing backup result data.
71
+
72
+ ```python
73
+ cloud.backups.delete(backup_id=42)
74
+ ```
75
+
76
+ ## Notes
77
+
78
+ - Backup **configuration** (creating new backup jobs, attaching them to instances) is done in the MTN Cloud Console under **Backups → Jobs**.
79
+ - Backup **results** and **executions** are accessible via the SDK.
80
+ - `b.instance_id` and `b.server_id` are convenience properties that extract IDs from the nested `instance`/`server` dict.
@@ -12,10 +12,13 @@ Use this guide in two ways:
12
12
  2. [Instances](./instances.md)
13
13
  3. [Networking](./networking.md)
14
14
  4. [Storage](./storage.md)
15
- 5. [Advanced Cookbook](./advanced-cookbook.md)
16
- 6. [API Overview](./api-overview.md)
17
- 7. [API Reference](./api-reference/index.md)
18
- 8. [Docstring Style Standard](./docstring-style.md)
15
+ 5. [Security Groups](./security-groups.md)
16
+ 6. [Backups](./backups.md)
17
+ 7. [Virtual Images](./virtual-images.md)
18
+ 8. [Advanced Cookbook](./advanced-cookbook.md)
19
+ 9. [API Overview](./api-overview.md)
20
+ 10. [API Reference](./api-reference/index.md)
21
+ 11. [Docstring Style Standard](./docstring-style.md)
19
22
 
20
23
  ## Who This Is For
21
24
 
@@ -36,6 +39,9 @@ Use this guide in two ways:
36
39
  2. Instances
37
40
  3. Networking
38
41
  4. Storage
39
- 5. API Overview
40
- 6. API Reference
41
- 7. Advanced Cookbook
42
+ 5. Security Groups
43
+ 6. Backups
44
+ 7. Virtual Images
45
+ 8. API Overview
46
+ 9. API Reference
47
+ 10. Advanced Cookbook
@@ -128,6 +128,33 @@ cloud.instances.wait_until_running(instance.id, timeout=300)
128
128
  cloud.instances.wait_for_status(instance.id, "suspended", timeout=120)
129
129
  ```
130
130
 
131
+ ## Snapshots
132
+
133
+ Snapshots capture the disk state of an instance at a point in time. Stop the instance before snapshotting to guarantee consistency.
134
+
135
+ ```python
136
+ # Create a snapshot
137
+ snap = cloud.instances.create_snapshot(
138
+ instance_id=123,
139
+ name="pre-upgrade",
140
+ description="State before OS upgrade",
141
+ )
142
+ print(snap.id, snap.name, snap.status)
143
+
144
+ # List all snapshots for an instance
145
+ snaps = cloud.instances.list_snapshots(instance_id=123)
146
+ for s in snaps:
147
+ print(s.id, s.name, s.snapshot_created)
148
+
149
+ # Revert to a snapshot (instance must be stopped)
150
+ cloud.instances.stop(123)
151
+ cloud.instances.wait_until_stopped(123)
152
+ cloud.instances.revert_snapshot(instance_id=123, snapshot_id=snap.id)
153
+
154
+ # Delete a snapshot
155
+ cloud.instances.delete_snapshot(instance_id=123, snapshot_id=snap.id)
156
+ ```
157
+
131
158
  ## Common Pitfalls
132
159
 
133
160
  - **Resource pool not ready.** The SDK call will fail if you run it before the ~10 minute provisioning window completes. Wait and retry.
@@ -97,4 +97,4 @@ print(allocated.id, allocated.ip_address)
97
97
 
98
98
  - Many networking fields are OpenStack-specific. The SDK exposes the fields most relevant to MTN Cloud's environment.
99
99
  - Always discover and validate IDs (`cloud_id`, `group_id`, `type_id`) for your own account — they are tenant-specific and differ between environments.
100
- - Security groups (firewall rules) are separate from network configuration. Manage them in **Infrastructure → Network → Security Groups** in the console.
100
+ - Security groups (firewall rules) are separate from network configuration. Manage them via `cloud.security_groups` — see the [Security Groups guide](./security-groups.md).