mtn-cloud 0.2.16__tar.gz → 0.2.19__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.
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/PKG-INFO +111 -14
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/README.md +110 -13
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/api-overview.md +20 -1
- mtn_cloud-0.2.19/docs/api-reference/backups.md +59 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/api-reference/index.md +3 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/api-reference/instances.md +67 -2
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/api-reference/networks.md +16 -20
- mtn_cloud-0.2.19/docs/api-reference/security-groups.md +94 -0
- mtn_cloud-0.2.19/docs/api-reference/virtual-images.md +37 -0
- mtn_cloud-0.2.19/docs/backups.md +80 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/index.md +13 -7
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/instances.md +82 -11
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/networking.md +24 -28
- mtn_cloud-0.2.19/docs/security-groups.md +146 -0
- mtn_cloud-0.2.19/docs/virtual-images.md +65 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/_version.py +1 -1
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/client.py +59 -3
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/config.py +1 -7
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/http.py +0 -13
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/models/__init__.py +36 -2
- mtn_cloud-0.2.19/src/mtn_cloud/models/backup.py +93 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/models/base.py +3 -6
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/models/cloud.py +0 -10
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/models/group.py +0 -8
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/models/instance.py +3 -55
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/models/instance_type.py +0 -8
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/models/network.py +43 -19
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/models/plan.py +0 -8
- mtn_cloud-0.2.19/src/mtn_cloud/models/resource_pool.py +50 -0
- mtn_cloud-0.2.19/src/mtn_cloud/models/security_group.py +195 -0
- mtn_cloud-0.2.19/src/mtn_cloud/models/snapshot.py +54 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/models/user.py +0 -6
- mtn_cloud-0.2.19/src/mtn_cloud/models/virtual_image.py +57 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/models/volume.py +1 -10
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/resources/__init__.py +8 -0
- mtn_cloud-0.2.19/src/mtn_cloud/resources/backups.py +173 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/resources/instances.py +278 -14
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/resources/networks.py +63 -45
- mtn_cloud-0.2.19/src/mtn_cloud/resources/security_groups.py +350 -0
- mtn_cloud-0.2.19/src/mtn_cloud/resources/virtual_images.py +124 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/tests/conftest.py +20 -3
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/tests/test_archive_buckets.py +62 -76
- mtn_cloud-0.2.19/tests/test_backups.py +163 -0
- mtn_cloud-0.2.19/tests/test_client.py +230 -0
- mtn_cloud-0.2.19/tests/test_clouds.py +102 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/tests/test_config.py +65 -58
- mtn_cloud-0.2.19/tests/test_groups.py +69 -0
- mtn_cloud-0.2.19/tests/test_instance_types.py +370 -0
- mtn_cloud-0.2.19/tests/test_instances.py +549 -0
- mtn_cloud-0.2.19/tests/test_networks.py +445 -0
- mtn_cloud-0.2.19/tests/test_plans.py +107 -0
- mtn_cloud-0.2.19/tests/test_security_groups.py +239 -0
- mtn_cloud-0.2.19/tests/test_storage_buckets.py +256 -0
- mtn_cloud-0.2.19/tests/test_virtual_images.py +117 -0
- mtn_cloud-0.2.16/tests/test_client.py +0 -183
- mtn_cloud-0.2.16/tests/test_clouds.py +0 -50
- mtn_cloud-0.2.16/tests/test_instance_types.py +0 -325
- mtn_cloud-0.2.16/tests/test_instances.py +0 -367
- mtn_cloud-0.2.16/tests/test_networks.py +0 -256
- mtn_cloud-0.2.16/tests/test_storage_buckets.py +0 -152
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/.gitignore +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/LICENSE +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/advanced-cookbook.md +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/api-reference/archive-buckets.md +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/api-reference/client.md +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/api-reference/clouds.md +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/api-reference/groups.md +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/api-reference/instance-types.md +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/api-reference/plans.md +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/api-reference/storage-buckets.md +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/docstring-style.md +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/quickstart.md +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/storage.md +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/docs/stylesheets/extra.css +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/pyproject.toml +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/__init__.py +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/exceptions.py +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/models/archive.py +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/models/storage_bucket.py +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/resources/archive_buckets.py +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/resources/base.py +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/resources/clouds.py +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/resources/groups.py +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/resources/instance_types.py +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/resources/plans.py +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/src/mtn_cloud/resources/storage_buckets.py +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/tests/__init__.py +0 -0
- {mtn_cloud-0.2.16 → mtn_cloud-0.2.19}/tests/test_exceptions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mtn-cloud
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.19
|
|
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
|
[](https://www.python.org/downloads/)
|
|
51
51
|
[](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
|
|
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/)
|
|
@@ -124,23 +127,45 @@ User Icon (top-right) -> User Settings -> API Access.
|
|
|
124
127
|
|
|
125
128
|
### 1. Discover Reference Data
|
|
126
129
|
|
|
127
|
-
Use these lookups before provisioning so your scripts stay deterministic.
|
|
130
|
+
Use these lookups before provisioning so your scripts stay deterministic. They all use permission-safe endpoints (the admin-level `clouds`/`plans` endpoints are restricted on most tenant accounts — you don't need them).
|
|
128
131
|
|
|
129
132
|
```python
|
|
130
|
-
# Groups (sites)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
133
|
+
# Groups (sites) — also carry the cloud/zone IDs you need
|
|
134
|
+
group = cloud.groups.get_by_name("MTNNG_CLOUD_AZ_1")
|
|
135
|
+
print(group.id, group.name, group.cloud_ids)
|
|
136
|
+
|
|
137
|
+
# Instance types — each carries its own default_layout_id
|
|
138
|
+
itype = cloud.instance_types.get_by_code("MTN-CS10")
|
|
139
|
+
print(itype.code, itype.default_layout_id)
|
|
140
|
+
|
|
141
|
+
# Resource pools — where the instance is hosted (the resource_pool_id)
|
|
142
|
+
for pool in cloud.instances.list_resource_pools(group="MTNNG_CLOUD_AZ_1"):
|
|
143
|
+
print(pool.code, pool.name)
|
|
144
|
+
|
|
145
|
+
# Service plans — CPU/memory/storage tiers for this zone + layout
|
|
146
|
+
for plan in cloud.instances.list_service_plans(
|
|
147
|
+
zone_id=group.cloud_ids[0],
|
|
148
|
+
layout_id=itype.default_layout_id,
|
|
149
|
+
group_id=group.id,
|
|
150
|
+
):
|
|
151
|
+
print(plan["id"], plan["name"])
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
A **resource pool is required** to create an instance — it's where the VM is hosted. Discover it by group name (the cloud/zone is resolved for you), or fetch one directly by name:
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
pool = cloud.instances.get_resource_pool(
|
|
158
|
+
"my-project-name",
|
|
159
|
+
group="MTNNG_CLOUD_AZ_1",
|
|
160
|
+
)
|
|
161
|
+
print(pool.code) # e.g. "pool-214" — pass this as resource_pool_id
|
|
139
162
|
```
|
|
140
163
|
|
|
141
164
|
### 2. Create an Instance
|
|
142
165
|
|
|
143
166
|
```python
|
|
167
|
+
pool = cloud.instances.get_resource_pool("my-project-name", group="MTNNG_CLOUD_AZ_1")
|
|
168
|
+
|
|
144
169
|
instance = cloud.instances.create(
|
|
145
170
|
name="my-server",
|
|
146
171
|
cloud="MTNNG_CLOUD_AZ_1",
|
|
@@ -148,7 +173,7 @@ instance = cloud.instances.create(
|
|
|
148
173
|
group="MTNNG_CLOUD_AZ_1",
|
|
149
174
|
layout=327,
|
|
150
175
|
plan=6776,
|
|
151
|
-
resource_pool_id="pool-214"
|
|
176
|
+
resource_pool_id=pool.code, # "pool-214" — or pass the numeric ID 214
|
|
152
177
|
labels=["production", "web"],
|
|
153
178
|
)
|
|
154
179
|
|
|
@@ -200,7 +225,79 @@ subnets = cloud.networks.list_subnets(new_network.id)
|
|
|
200
225
|
print(f"Subnets: {len(subnets)}")
|
|
201
226
|
```
|
|
202
227
|
|
|
203
|
-
### 5.
|
|
228
|
+
### 5. Manage Security Groups
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
# Create a security group and add rules
|
|
232
|
+
sg = cloud.security_groups.create(
|
|
233
|
+
name="web-servers",
|
|
234
|
+
description="HTTP, HTTPS, and SSH access",
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
cloud.security_groups.create_rule(
|
|
238
|
+
sg.id,
|
|
239
|
+
name="allow-ssh",
|
|
240
|
+
direction="ingress",
|
|
241
|
+
protocol="tcp",
|
|
242
|
+
port_range="22",
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
cloud.security_groups.create_rule(
|
|
246
|
+
sg.id,
|
|
247
|
+
name="allow-https",
|
|
248
|
+
direction="ingress",
|
|
249
|
+
protocol="tcp",
|
|
250
|
+
port_range="443",
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
# Use the security group when provisioning
|
|
254
|
+
instance = cloud.instances.create(
|
|
255
|
+
name="app-server-01",
|
|
256
|
+
cloud="MTNNG_CLOUD_AZ_1",
|
|
257
|
+
type="MTN-CS10",
|
|
258
|
+
group="MTNNG_CLOUD_AZ_1",
|
|
259
|
+
layout=327,
|
|
260
|
+
plan=6776,
|
|
261
|
+
resource_pool_id="pool-214",
|
|
262
|
+
security_group="web-servers",
|
|
263
|
+
)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### 6. Snapshot Instances
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
# Create a snapshot before a risky operation
|
|
270
|
+
snap = cloud.instances.create_snapshot(
|
|
271
|
+
instance_id=instance.id,
|
|
272
|
+
name="pre-upgrade",
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
# Revert if something goes wrong (stop the instance first)
|
|
276
|
+
cloud.instances.stop(instance.id)
|
|
277
|
+
cloud.instances.wait_until_stopped(instance.id)
|
|
278
|
+
cloud.instances.revert_snapshot(instance.id, snapshot_id=snap.id)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### 7. Work with Backups
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
# List configured backups and their status
|
|
285
|
+
for backup in cloud.backups.list():
|
|
286
|
+
print(f"{backup.name}: last_run={backup.last_run} status={backup.last_status}")
|
|
287
|
+
|
|
288
|
+
# Trigger an immediate backup run
|
|
289
|
+
cloud.backups.execute(backup_id=42)
|
|
290
|
+
|
|
291
|
+
# Check execution history
|
|
292
|
+
for result in cloud.backups.list_results(backup_id=42):
|
|
293
|
+
print(f"{result.start_date}: {result.status} ({result.size_in_mb} MB)")
|
|
294
|
+
|
|
295
|
+
# List and execute backup jobs (schedules)
|
|
296
|
+
for job in cloud.backups.list_jobs():
|
|
297
|
+
print(f"{job.name}: cron={job.cron_expression}")
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### 8. Work with Storage and Archives
|
|
204
301
|
|
|
205
302
|
```python
|
|
206
303
|
# Create S3-compatible storage provider
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://www.python.org/downloads/)
|
|
7
7
|
[](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
|
|
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/)
|
|
@@ -80,23 +83,45 @@ User Icon (top-right) -> User Settings -> API Access.
|
|
|
80
83
|
|
|
81
84
|
### 1. Discover Reference Data
|
|
82
85
|
|
|
83
|
-
Use these lookups before provisioning so your scripts stay deterministic.
|
|
86
|
+
Use these lookups before provisioning so your scripts stay deterministic. They all use permission-safe endpoints (the admin-level `clouds`/`plans` endpoints are restricted on most tenant accounts — you don't need them).
|
|
84
87
|
|
|
85
88
|
```python
|
|
86
|
-
# Groups (sites)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
89
|
+
# Groups (sites) — also carry the cloud/zone IDs you need
|
|
90
|
+
group = cloud.groups.get_by_name("MTNNG_CLOUD_AZ_1")
|
|
91
|
+
print(group.id, group.name, group.cloud_ids)
|
|
92
|
+
|
|
93
|
+
# Instance types — each carries its own default_layout_id
|
|
94
|
+
itype = cloud.instance_types.get_by_code("MTN-CS10")
|
|
95
|
+
print(itype.code, itype.default_layout_id)
|
|
96
|
+
|
|
97
|
+
# Resource pools — where the instance is hosted (the resource_pool_id)
|
|
98
|
+
for pool in cloud.instances.list_resource_pools(group="MTNNG_CLOUD_AZ_1"):
|
|
99
|
+
print(pool.code, pool.name)
|
|
100
|
+
|
|
101
|
+
# Service plans — CPU/memory/storage tiers for this zone + layout
|
|
102
|
+
for plan in cloud.instances.list_service_plans(
|
|
103
|
+
zone_id=group.cloud_ids[0],
|
|
104
|
+
layout_id=itype.default_layout_id,
|
|
105
|
+
group_id=group.id,
|
|
106
|
+
):
|
|
107
|
+
print(plan["id"], plan["name"])
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
A **resource pool is required** to create an instance — it's where the VM is hosted. Discover it by group name (the cloud/zone is resolved for you), or fetch one directly by name:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
pool = cloud.instances.get_resource_pool(
|
|
114
|
+
"my-project-name",
|
|
115
|
+
group="MTNNG_CLOUD_AZ_1",
|
|
116
|
+
)
|
|
117
|
+
print(pool.code) # e.g. "pool-214" — pass this as resource_pool_id
|
|
95
118
|
```
|
|
96
119
|
|
|
97
120
|
### 2. Create an Instance
|
|
98
121
|
|
|
99
122
|
```python
|
|
123
|
+
pool = cloud.instances.get_resource_pool("my-project-name", group="MTNNG_CLOUD_AZ_1")
|
|
124
|
+
|
|
100
125
|
instance = cloud.instances.create(
|
|
101
126
|
name="my-server",
|
|
102
127
|
cloud="MTNNG_CLOUD_AZ_1",
|
|
@@ -104,7 +129,7 @@ instance = cloud.instances.create(
|
|
|
104
129
|
group="MTNNG_CLOUD_AZ_1",
|
|
105
130
|
layout=327,
|
|
106
131
|
plan=6776,
|
|
107
|
-
resource_pool_id="pool-214"
|
|
132
|
+
resource_pool_id=pool.code, # "pool-214" — or pass the numeric ID 214
|
|
108
133
|
labels=["production", "web"],
|
|
109
134
|
)
|
|
110
135
|
|
|
@@ -156,7 +181,79 @@ subnets = cloud.networks.list_subnets(new_network.id)
|
|
|
156
181
|
print(f"Subnets: {len(subnets)}")
|
|
157
182
|
```
|
|
158
183
|
|
|
159
|
-
### 5.
|
|
184
|
+
### 5. Manage Security Groups
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
# Create a security group and add rules
|
|
188
|
+
sg = cloud.security_groups.create(
|
|
189
|
+
name="web-servers",
|
|
190
|
+
description="HTTP, HTTPS, and SSH access",
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
cloud.security_groups.create_rule(
|
|
194
|
+
sg.id,
|
|
195
|
+
name="allow-ssh",
|
|
196
|
+
direction="ingress",
|
|
197
|
+
protocol="tcp",
|
|
198
|
+
port_range="22",
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
cloud.security_groups.create_rule(
|
|
202
|
+
sg.id,
|
|
203
|
+
name="allow-https",
|
|
204
|
+
direction="ingress",
|
|
205
|
+
protocol="tcp",
|
|
206
|
+
port_range="443",
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
# Use the security group when provisioning
|
|
210
|
+
instance = cloud.instances.create(
|
|
211
|
+
name="app-server-01",
|
|
212
|
+
cloud="MTNNG_CLOUD_AZ_1",
|
|
213
|
+
type="MTN-CS10",
|
|
214
|
+
group="MTNNG_CLOUD_AZ_1",
|
|
215
|
+
layout=327,
|
|
216
|
+
plan=6776,
|
|
217
|
+
resource_pool_id="pool-214",
|
|
218
|
+
security_group="web-servers",
|
|
219
|
+
)
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### 6. Snapshot Instances
|
|
223
|
+
|
|
224
|
+
```python
|
|
225
|
+
# Create a snapshot before a risky operation
|
|
226
|
+
snap = cloud.instances.create_snapshot(
|
|
227
|
+
instance_id=instance.id,
|
|
228
|
+
name="pre-upgrade",
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
# Revert if something goes wrong (stop the instance first)
|
|
232
|
+
cloud.instances.stop(instance.id)
|
|
233
|
+
cloud.instances.wait_until_stopped(instance.id)
|
|
234
|
+
cloud.instances.revert_snapshot(instance.id, snapshot_id=snap.id)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### 7. Work with Backups
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
# List configured backups and their status
|
|
241
|
+
for backup in cloud.backups.list():
|
|
242
|
+
print(f"{backup.name}: last_run={backup.last_run} status={backup.last_status}")
|
|
243
|
+
|
|
244
|
+
# Trigger an immediate backup run
|
|
245
|
+
cloud.backups.execute(backup_id=42)
|
|
246
|
+
|
|
247
|
+
# Check execution history
|
|
248
|
+
for result in cloud.backups.list_results(backup_id=42):
|
|
249
|
+
print(f"{result.start_date}: {result.status} ({result.size_in_mb} MB)")
|
|
250
|
+
|
|
251
|
+
# List and execute backup jobs (schedules)
|
|
252
|
+
for job in cloud.backups.list_jobs():
|
|
253
|
+
print(f"{job.name}: cron={job.cron_expression}")
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### 8. Work with Storage and Archives
|
|
160
257
|
|
|
161
258
|
```python
|
|
162
259
|
# 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
|
|
|
@@ -39,10 +42,16 @@ cloud.instance_types.get_by_code("MTN-CS10")
|
|
|
39
42
|
## Common Write Operations
|
|
40
43
|
|
|
41
44
|
```python
|
|
42
|
-
|
|
45
|
+
# Discover the resource pool an instance will be hosted in
|
|
46
|
+
pool = cloud.instances.get_resource_pool("my-project", group="MTNNG_CLOUD_AZ_1")
|
|
47
|
+
|
|
48
|
+
cloud.instances.create(..., resource_pool_id=pool.code)
|
|
43
49
|
cloud.instances.update(instance_id=123, name="new-name")
|
|
44
50
|
cloud.instances.delete(123)
|
|
45
51
|
|
|
52
|
+
cloud.instances.create_snapshot(123, "pre-upgrade")
|
|
53
|
+
cloud.instances.revert_snapshot(123, snapshot_id=456)
|
|
54
|
+
|
|
46
55
|
cloud.networks.create(...)
|
|
47
56
|
cloud.networks.update(298, description="updated")
|
|
48
57
|
cloud.networks.delete(298)
|
|
@@ -50,6 +59,11 @@ cloud.networks.delete(298)
|
|
|
50
59
|
cloud.storage_buckets.create_s3(...)
|
|
51
60
|
cloud.archive_buckets.create(...)
|
|
52
61
|
cloud.archive_buckets.upload_file(...)
|
|
62
|
+
|
|
63
|
+
cloud.security_groups.create(name="web-servers")
|
|
64
|
+
cloud.security_groups.create_rule(sg_id, direction="ingress", protocol="tcp", port_range="22")
|
|
65
|
+
|
|
66
|
+
cloud.backups.execute(backup_id=42)
|
|
53
67
|
```
|
|
54
68
|
|
|
55
69
|
## Exception Hierarchy
|
|
@@ -80,6 +94,11 @@ Resource methods return typed Pydantic models, for example:
|
|
|
80
94
|
- `StorageBucket`
|
|
81
95
|
- `ArchiveBucket`
|
|
82
96
|
- `ArchiveFile`
|
|
97
|
+
- `SecurityGroup`, `SecurityGroupRule`
|
|
98
|
+
- `Snapshot`
|
|
99
|
+
- `ResourcePool`
|
|
100
|
+
- `Backup`, `BackupJob`, `BackupResult`
|
|
101
|
+
- `VirtualImage`
|
|
83
102
|
|
|
84
103
|
## Naming Conventions
|
|
85
104
|
|
|
@@ -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
|
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
- common API exceptions
|
|
33
33
|
- `NotFoundError` when no instance matches
|
|
34
34
|
|
|
35
|
-
### `create(name: str, *, cloud: str, type: str, group: str, layout: int, plan: int, resource_pool_id: str, description=None, environment=None, labels=None, tags=None, copies=1, layout_size=1, availability_zone=None, security_group="default", os_external_network_id=None, create_user=True, workflow_id=None, shutdown_days=None, expire_days=None, create_backup=None, security_groups=None, ports=None, volumes=None, network_interfaces=None, options=None) -> Instance`
|
|
35
|
+
### `create(name: str, *, cloud: str, type: str, group: str, layout: int, plan: int, resource_pool_id: str | int, description=None, environment=None, labels=None, tags=None, copies=1, layout_size=1, availability_zone=None, security_group="default", os_external_network_id=None, create_user=True, workflow_id=None, shutdown_days=None, expire_days=None, create_backup=None, security_groups=None, ports=None, volumes=None, network_interfaces=None, options=None) -> Instance`
|
|
36
36
|
|
|
37
37
|
- Endpoint sequence:
|
|
38
38
|
- `GET /api/groups?name=<group>&max=1` (resolve group name to `group_id`)
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
- `group`: group/site name (resolved to ID)
|
|
46
46
|
- `layout`: layout ID
|
|
47
47
|
- `plan`: service plan ID
|
|
48
|
-
- `resource_pool_id`:
|
|
48
|
+
- `resource_pool_id`: resource pool code (`"pool-214"`) or numeric ID (`214`); both normalize to the code. Discover with `list_resource_pools()` / `get_resource_pool()`
|
|
49
49
|
- Optional metadata:
|
|
50
50
|
- `description`, `environment`, `labels`, `tags`
|
|
51
51
|
- Optional sizing/provisioning:
|
|
@@ -165,3 +165,68 @@ 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
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Provisioning discovery
|
|
204
|
+
|
|
205
|
+
These helpers resolve the IDs and codes required by `create()` using permission-safe endpoints (the admin-level `clouds`/`plans` endpoints are restricted on most accounts).
|
|
206
|
+
|
|
207
|
+
### `list_resource_pools(group=None, *, cloud_id=None, group_id=None, provision_type_code="openstack") -> list[ResourcePool]`
|
|
208
|
+
|
|
209
|
+
- Endpoint: `GET /api/options/zonePools?cloudId={cloud_id}&groupId={group_id}`
|
|
210
|
+
- A resource pool is where an instance is hosted; its `code` is the `resource_pool_id` for `create()`
|
|
211
|
+
- Parameters:
|
|
212
|
+
- `group`: group name or ID — when given, `cloud_id` and `group_id` are resolved from it automatically (the group embeds its cloud/zone IDs)
|
|
213
|
+
- `cloud_id` / `group_id`: explicit IDs, required if `group` is not given
|
|
214
|
+
- `provision_type_code`: provisioning type, defaults to `"openstack"`
|
|
215
|
+
- Returns: `list[ResourcePool]` (group-header rows are filtered out)
|
|
216
|
+
- Raises: `ValueError` if neither `group` nor both `cloud_id`/`group_id` are provided, or the group has no associated cloud
|
|
217
|
+
|
|
218
|
+
### `get_resource_pool(name: str, *, group=None, cloud_id=None, group_id=None, provision_type_code="openstack") -> ResourcePool`
|
|
219
|
+
|
|
220
|
+
- Fetches a single pool by display name **or** code (e.g. `"pool-214"`)
|
|
221
|
+
- Same resolution rules as `list_resource_pools`
|
|
222
|
+
- Returns: `ResourcePool`
|
|
223
|
+
- Raises: `NotFoundError` if no pool matches `name`
|
|
224
|
+
|
|
225
|
+
### `list_service_plans(zone_id=None, layout_id=None, group_id=None) -> list[dict[str, Any]]`
|
|
226
|
+
|
|
227
|
+
- Endpoint: `GET /api/instances/service-plans?zoneId={zone_id}&layoutId={layout_id}&siteId={group_id}`
|
|
228
|
+
- Returns available service plans (CPU/memory/storage tiers) scoped to the provisioning context
|
|
229
|
+
- `layout_id` is required by the API; use `instance_type.default_layout_id`
|
|
230
|
+
- Returns: list of plan dicts from response key `plans`
|
|
231
|
+
|
|
232
|
+
**`ResourcePool` model fields:** `id` (numeric), `code` (alias of API `value`, e.g. `"pool-214"`), `name`, `external_id` (OpenStack pool ID), `is_default`.
|
|
@@ -88,36 +88,32 @@
|
|
|
88
88
|
- Returns: `NetworkTypeInfo`
|
|
89
89
|
- Raises: common API exceptions
|
|
90
90
|
|
|
91
|
-
### `
|
|
91
|
+
### `list_pools(max_results=None, offset=0, phrase=None) -> list[NetworkPool]`
|
|
92
92
|
|
|
93
|
-
- Endpoint: `GET /api/networks/
|
|
93
|
+
- Endpoint: `GET /api/networks/pools`
|
|
94
94
|
- Parameters:
|
|
95
|
+
- `max_results`: maps to query `max`
|
|
96
|
+
- `offset`: pagination offset
|
|
95
97
|
- `phrase`: search phrase
|
|
96
|
-
|
|
97
|
-
- `ip_status`: provider status value
|
|
98
|
-
- `cloud_id`: mapped to `zoneId`
|
|
99
|
-
- `server_id`: mapped to `serverId`
|
|
100
|
-
- Returns: `list[NetworkFloatingIP]`
|
|
98
|
+
- Returns: `list[NetworkPool]` (each includes its `ip_ranges`, `ip_count`, `free_count`)
|
|
101
99
|
- Raises: common API exceptions
|
|
102
100
|
|
|
103
|
-
### `
|
|
101
|
+
### `get_pool(pool_id: int) -> NetworkPool`
|
|
104
102
|
|
|
105
|
-
- Endpoint: `GET /api/networks/
|
|
106
|
-
- Returns: `
|
|
103
|
+
- Endpoint: `GET /api/networks/pools/{pool_id}`
|
|
104
|
+
- Returns: `NetworkPool`
|
|
107
105
|
- Raises: common API exceptions
|
|
108
106
|
|
|
109
|
-
### `
|
|
107
|
+
### `list_pool_ips(pool_id: int, *, max_results=None, phrase=None, ip_address=None, hostname=None) -> list[NetworkPoolIp]`
|
|
110
108
|
|
|
111
|
-
- Endpoint: `
|
|
109
|
+
- Endpoint: `GET /api/networks/pools/{pool_id}/ips`
|
|
112
110
|
- Parameters:
|
|
113
|
-
- `
|
|
114
|
-
- `
|
|
115
|
-
-
|
|
111
|
+
- `max_results`: maps to query `max`
|
|
112
|
+
- `phrase`: partial match on `ipAddress` or `hostname`
|
|
113
|
+
- `ip_address`: exact IP match
|
|
114
|
+
- `hostname`: exact hostname match
|
|
115
|
+
- Returns: `list[NetworkPoolIp]`
|
|
116
116
|
- Raises: common API exceptions
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
- Endpoint: `PUT /api/networks/floating-ips/{floating_ip_id}/release`
|
|
121
|
-
- Returns: `True`
|
|
122
|
-
- Raises: common API exceptions
|
|
118
|
+
> **Note:** Standalone floating-IP endpoints (`/api/networks/floating-ips`) are restricted (HTTP 403) on MTN Cloud tenant accounts and are not exposed by the SDK. Assign external/public connectivity at provisioning time via the instance's `os_external_network_id` instead.
|
|
123
119
|
|