mtn-cloud 0.2.2__tar.gz → 0.2.6__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.2 → mtn_cloud-0.2.6}/PKG-INFO +6 -5
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/README.md +3 -2
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/docs/api-overview.md +3 -2
- mtn_cloud-0.2.6/docs/api-reference/archive-buckets.md +134 -0
- mtn_cloud-0.2.6/docs/api-reference/client.md +44 -0
- mtn_cloud-0.2.6/docs/api-reference/clouds.md +40 -0
- mtn_cloud-0.2.6/docs/api-reference/groups.md +26 -0
- mtn_cloud-0.2.6/docs/api-reference/index.md +80 -0
- mtn_cloud-0.2.6/docs/api-reference/instance-types.md +62 -0
- mtn_cloud-0.2.6/docs/api-reference/instances.md +167 -0
- mtn_cloud-0.2.6/docs/api-reference/networks.md +123 -0
- mtn_cloud-0.2.6/docs/api-reference/plans.md +41 -0
- mtn_cloud-0.2.6/docs/api-reference/storage-buckets.md +69 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/docs/index.md +5 -3
- mtn_cloud-0.2.6/docs/stylesheets/extra.css +30 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/pyproject.toml +2 -2
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/_version.py +1 -1
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/client.py +1 -1
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/models/storage_bucket.py +1 -1
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/resources/archive_buckets.py +1 -1
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/resources/storage_buckets.py +1 -1
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/tests/test_archive_buckets.py +3 -3
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/tests/test_instance_types.py +8 -8
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/.gitignore +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/LICENSE +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/docs/advanced-cookbook.md +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/docs/docstring-style.md +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/docs/instances.md +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/docs/networking.md +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/docs/quickstart.md +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/docs/storage.md +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/__init__.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/config.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/exceptions.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/http.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/models/__init__.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/models/archive.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/models/base.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/models/cloud.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/models/group.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/models/instance.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/models/instance_type.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/models/network.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/models/plan.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/models/user.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/models/volume.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/resources/__init__.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/resources/base.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/resources/clouds.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/resources/groups.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/resources/instance_types.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/resources/instances.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/resources/networks.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/src/mtn_cloud/resources/plans.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/tests/__init__.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/tests/conftest.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/tests/test_client.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/tests/test_clouds.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/tests/test_config.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/tests/test_exceptions.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/tests/test_instances.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/tests/test_networks.py +0 -0
- {mtn_cloud-0.2.2 → mtn_cloud-0.2.6}/tests/test_storage_buckets.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mtn-cloud
|
|
3
|
-
Version: 0.2.
|
|
4
|
-
Summary: Community Python SDK for MTN Cloud
|
|
3
|
+
Version: 0.2.6
|
|
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
|
|
7
7
|
Project-URL: Repository, https://github.com/mahveotm/mtn-cloud-python
|
|
@@ -10,7 +10,7 @@ Author-email: Marvellous Osuolale <m@rvellous.com>
|
|
|
10
10
|
Maintainer-email: Marvellous Osuolale <m@rvellous.com>
|
|
11
11
|
License: MIT
|
|
12
12
|
License-File: LICENSE
|
|
13
|
-
Keywords: api,cloud,devops,infrastructure,
|
|
13
|
+
Keywords: api,cloud,devops,infrastructure,mtn,mtn-cloud,sdk
|
|
14
14
|
Classifier: Development Status :: 4 - Beta
|
|
15
15
|
Classifier: Intended Audience :: Developers
|
|
16
16
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -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)
|
|
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.
|
|
54
54
|
|
|
55
55
|
Docs: [mtn-cloud-python](https://mahveotm.github.io/mtn-cloud-python/)
|
|
56
56
|
|
|
@@ -80,6 +80,7 @@ pip install mtn-cloud
|
|
|
80
80
|
- [Storage](https://mahveotm.github.io/mtn-cloud-python/storage/)
|
|
81
81
|
- [Advanced Cookbook](https://mahveotm.github.io/mtn-cloud-python/advanced-cookbook/)
|
|
82
82
|
- [API Overview](https://mahveotm.github.io/mtn-cloud-python/api-overview/)
|
|
83
|
+
- [API Reference](https://mahveotm.github.io/mtn-cloud-python/api-reference/)
|
|
83
84
|
- [Docstring Style Standard](https://mahveotm.github.io/mtn-cloud-python/docstring-style/)
|
|
84
85
|
|
|
85
86
|
## Quick Start
|
|
@@ -348,6 +349,6 @@ MIT License. See [LICENSE](LICENSE) for details.
|
|
|
348
349
|
|
|
349
350
|
- [MTN Cloud Console](https://console.cloud.mtn.ng)
|
|
350
351
|
- [MTN Cloud Guide](https://cloud.mtn.ng/documentation)
|
|
351
|
-
- [Morpheus API Documentation](https://apidocs.morpheusdata.com/)
|
|
352
|
+
- [Morpheus API Documentation (supplementary)](https://apidocs.morpheusdata.com/)
|
|
352
353
|
- [GitHub Repository](https://github.com/mahveotm/mtn-cloud-python)
|
|
353
354
|
- [PyPI Package](https://pypi.org/project/mtn-cloud/)
|
|
@@ -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)
|
|
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.
|
|
10
10
|
|
|
11
11
|
Docs: [mtn-cloud-python](https://mahveotm.github.io/mtn-cloud-python/)
|
|
12
12
|
|
|
@@ -36,6 +36,7 @@ pip install mtn-cloud
|
|
|
36
36
|
- [Storage](https://mahveotm.github.io/mtn-cloud-python/storage/)
|
|
37
37
|
- [Advanced Cookbook](https://mahveotm.github.io/mtn-cloud-python/advanced-cookbook/)
|
|
38
38
|
- [API Overview](https://mahveotm.github.io/mtn-cloud-python/api-overview/)
|
|
39
|
+
- [API Reference](https://mahveotm.github.io/mtn-cloud-python/api-reference/)
|
|
39
40
|
- [Docstring Style Standard](https://mahveotm.github.io/mtn-cloud-python/docstring-style/)
|
|
40
41
|
|
|
41
42
|
## Quick Start
|
|
@@ -304,6 +305,6 @@ MIT License. See [LICENSE](LICENSE) for details.
|
|
|
304
305
|
|
|
305
306
|
- [MTN Cloud Console](https://console.cloud.mtn.ng)
|
|
306
307
|
- [MTN Cloud Guide](https://cloud.mtn.ng/documentation)
|
|
307
|
-
- [Morpheus API Documentation](https://apidocs.morpheusdata.com/)
|
|
308
|
+
- [Morpheus API Documentation (supplementary)](https://apidocs.morpheusdata.com/)
|
|
308
309
|
- [GitHub Repository](https://github.com/mahveotm/mtn-cloud-python)
|
|
309
310
|
- [PyPI Package](https://pypi.org/project/mtn-cloud/)
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
This page summarizes the public SDK surface.
|
|
4
4
|
|
|
5
|
+
For endpoint-by-endpoint signatures, parameters, return types, and raised exceptions, see [API Reference](./api-reference/index.md).
|
|
6
|
+
|
|
5
7
|
## Entry Point
|
|
6
8
|
|
|
7
9
|
```python
|
|
@@ -79,8 +81,7 @@ Resource methods return typed Pydantic models, for example:
|
|
|
79
81
|
|
|
80
82
|
## Naming Conventions
|
|
81
83
|
|
|
82
|
-
- `*_id` means numeric
|
|
84
|
+
- `*_id` means numeric MTN Cloud resource ID.
|
|
83
85
|
- `bucket_name` in archive methods means archive bucket name.
|
|
84
86
|
- `remote_path` means path inside archive storage.
|
|
85
87
|
- `local_path` / `local_directory` refer to local filesystem paths.
|
|
86
|
-
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Resource: `cloud.archive_buckets` (`ArchiveBucketsResource`)
|
|
2
|
+
|
|
3
|
+
### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, **filters) -> list[ArchiveBucket]`
|
|
4
|
+
|
|
5
|
+
- Endpoint: `GET /api/archives/buckets`
|
|
6
|
+
- Parameters:
|
|
7
|
+
- Shared list args
|
|
8
|
+
- `name`: archive bucket name filter
|
|
9
|
+
- Returns: `list[ArchiveBucket]`
|
|
10
|
+
- Raises: common API exceptions
|
|
11
|
+
|
|
12
|
+
### `get(archive_bucket_id: int) -> ArchiveBucket`
|
|
13
|
+
|
|
14
|
+
- Endpoint: `GET /api/archives/buckets/{archive_bucket_id}`
|
|
15
|
+
- Returns: `ArchiveBucket`
|
|
16
|
+
- Raises: common API exceptions
|
|
17
|
+
|
|
18
|
+
### `get_by_name(name: str) -> ArchiveBucket`
|
|
19
|
+
|
|
20
|
+
- Endpoint sequence:
|
|
21
|
+
- `GET /api/archives/buckets?name=<name>&max=1`
|
|
22
|
+
- Returns: `ArchiveBucket`
|
|
23
|
+
- Raises:
|
|
24
|
+
- common API exceptions
|
|
25
|
+
- `NotFoundError` when no match
|
|
26
|
+
|
|
27
|
+
### `create(name: str, *, storage_provider_id: int, description=None, visibility="private", is_public=False, account_id=None) -> ArchiveBucket`
|
|
28
|
+
|
|
29
|
+
- Endpoint: `POST /api/archives/buckets`
|
|
30
|
+
- Parameters:
|
|
31
|
+
- `name`: globally unique archive bucket name
|
|
32
|
+
- `storage_provider_id`: linked storage bucket/provider ID
|
|
33
|
+
- `description`: optional description
|
|
34
|
+
- `visibility`: `private` or `public`
|
|
35
|
+
- `is_public`: enable anonymous public URL support
|
|
36
|
+
- `account_id`: optional tenant account override
|
|
37
|
+
- Returns: `ArchiveBucket`
|
|
38
|
+
- Raises: common API exceptions
|
|
39
|
+
|
|
40
|
+
### `update(archive_bucket_id: int, *, name=None, description=None, visibility=None, is_public=None, account_id=None) -> ArchiveBucket`
|
|
41
|
+
|
|
42
|
+
- Endpoint: `PUT /api/archives/buckets/{archive_bucket_id}`
|
|
43
|
+
- Returns: `ArchiveBucket`
|
|
44
|
+
- Raises: common API exceptions
|
|
45
|
+
|
|
46
|
+
### `delete(archive_bucket_id: int) -> bool`
|
|
47
|
+
|
|
48
|
+
- Endpoint: `DELETE /api/archives/buckets/{archive_bucket_id}`
|
|
49
|
+
- Returns: `True`
|
|
50
|
+
- Raises: common API exceptions
|
|
51
|
+
|
|
52
|
+
### `list_files(*, bucket_name: str, remote_path: str | None = None, name: str | None = None, phrase: str | None = None, full_tree: bool | None = None) -> list[ArchiveFile]`
|
|
53
|
+
|
|
54
|
+
- Endpoint: `GET /api/archives/buckets/{bucket_name}/files/{remote_path}`
|
|
55
|
+
- Parameters:
|
|
56
|
+
- `bucket_name`: archive bucket name (not storage provider name)
|
|
57
|
+
- `remote_path`: archive path to list (defaults to `/`)
|
|
58
|
+
- `name`: exact file name filter
|
|
59
|
+
- `phrase`: wildcard phrase filter
|
|
60
|
+
- `full_tree`: include nested paths
|
|
61
|
+
- Returns: `list[ArchiveFile]`
|
|
62
|
+
- Raises: common API exceptions
|
|
63
|
+
|
|
64
|
+
### `upload_file(*, bucket_name: str, remote_path: str, local_path: str | Path, filename: str | None = None) -> ArchiveFile`
|
|
65
|
+
|
|
66
|
+
- Endpoint: `POST /api/archives/buckets/{bucket_name}/files/{remote_path}` (multipart)
|
|
67
|
+
- Parameters:
|
|
68
|
+
- `bucket_name`: destination archive bucket name
|
|
69
|
+
- `remote_path`: destination directory path
|
|
70
|
+
- `local_path`: local file path to upload
|
|
71
|
+
- `filename`: optional destination filename override
|
|
72
|
+
- Returns: `ArchiveFile`
|
|
73
|
+
- Raises:
|
|
74
|
+
- common API exceptions
|
|
75
|
+
- `FileNotFoundError` if `local_path` does not exist
|
|
76
|
+
- `ValueError` for invalid filename (empty, hidden name, spaces, unsupported chars)
|
|
77
|
+
- `NotFoundError` with enriched message when destination bucket/path does not exist
|
|
78
|
+
|
|
79
|
+
### `upload_directory(*, bucket_name: str, remote_path: str, local_directory: str | Path, recursive: bool = True, dry_run: bool = False, strict: bool = False) -> ArchiveDirectoryUploadResult`
|
|
80
|
+
|
|
81
|
+
Bulk upload helper with preflight classification.
|
|
82
|
+
|
|
83
|
+
- Endpoint behavior:
|
|
84
|
+
- Local preflight scan/validation
|
|
85
|
+
- Multiple `POST /api/archives/buckets/{bucket_name}/files/{destination_remote_path}` calls for eligible files
|
|
86
|
+
- Parameters:
|
|
87
|
+
- `bucket_name`: destination archive bucket
|
|
88
|
+
- `remote_path`: base destination directory
|
|
89
|
+
- `local_directory`: source directory
|
|
90
|
+
- `recursive`: include nested files
|
|
91
|
+
- `dry_run`: only preflight, no uploads
|
|
92
|
+
- `strict`: abort upload phase if preflight has skipped files
|
|
93
|
+
- Returns: `ArchiveDirectoryUploadResult` with `scanned`, `eligible`, `skipped`, `uploaded`, `failed`, plus per-file details
|
|
94
|
+
- Raises:
|
|
95
|
+
- `FileNotFoundError` if `local_directory` does not exist
|
|
96
|
+
- `NotADirectoryError` if `local_directory` is not a directory
|
|
97
|
+
- Other exceptions are generally captured into `failed_files`/`skipped_files` entries instead of being raised
|
|
98
|
+
|
|
99
|
+
### `download_file(*, bucket_name: str, remote_path: str, local_path: str | Path | None = None) -> bytes | Path`
|
|
100
|
+
|
|
101
|
+
- Endpoint: `GET /api/archives/download/{bucket_name}/{remote_path}`
|
|
102
|
+
- Parameters:
|
|
103
|
+
- `local_path`: optional save target; when omitted returns bytes in memory
|
|
104
|
+
- Returns:
|
|
105
|
+
- `bytes` when `local_path` is `None`
|
|
106
|
+
- `Path` when written to disk
|
|
107
|
+
- Raises:
|
|
108
|
+
- common API exceptions
|
|
109
|
+
- filesystem exceptions if writing to `local_path` fails
|
|
110
|
+
|
|
111
|
+
### `copy_file(*, source_bucket_name: str, source_path: str, destination_bucket_name: str, destination_path: str | None = None, destination_filename: str | None = None) -> ArchiveFile`
|
|
112
|
+
|
|
113
|
+
Copy helper implemented as download + upload.
|
|
114
|
+
|
|
115
|
+
- Endpoint sequence:
|
|
116
|
+
- `GET /api/archives/download/{source_bucket_name}/{source_path}`
|
|
117
|
+
- `POST /api/archives/buckets/{destination_bucket_name}/files/{destination_path or "/"}`
|
|
118
|
+
- Returns: copied `ArchiveFile`
|
|
119
|
+
- Raises:
|
|
120
|
+
- common API exceptions
|
|
121
|
+
- any local/file validation exceptions from `download_file(...)` or `upload_file(...)`
|
|
122
|
+
|
|
123
|
+
### `get_file(archive_file_id: int) -> ArchiveFile`
|
|
124
|
+
|
|
125
|
+
- Endpoint: `GET /api/archives/files/{archive_file_id}`
|
|
126
|
+
- Returns: `ArchiveFile`
|
|
127
|
+
- Raises: common API exceptions
|
|
128
|
+
|
|
129
|
+
### `delete_file(archive_file_id: int) -> bool`
|
|
130
|
+
|
|
131
|
+
- Endpoint: `DELETE /api/archives/files/{archive_file_id}`
|
|
132
|
+
- Returns: `True`
|
|
133
|
+
- Raises: common API exceptions
|
|
134
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Client: `MTNCloud`
|
|
2
|
+
|
|
3
|
+
### `MTNCloud(token=None, username=None, password=None, url=None, timeout=None, verify_ssl=True, config=None)`
|
|
4
|
+
|
|
5
|
+
Creates an SDK client and lazy-loads resource managers.
|
|
6
|
+
|
|
7
|
+
- Endpoint: None (constructor does not make API calls)
|
|
8
|
+
- Parameters:
|
|
9
|
+
- `token`: API bearer token (recommended)
|
|
10
|
+
- `username`, `password`: OAuth password-grant alternative
|
|
11
|
+
- `url`: MTN Cloud base console URL, no `/api` needed
|
|
12
|
+
- `timeout`: request timeout in seconds
|
|
13
|
+
- `verify_ssl`: enable/disable TLS certificate validation
|
|
14
|
+
- `config`: explicit `MTNCloudConfig` object (overrides other args)
|
|
15
|
+
- Returns: `MTNCloud`
|
|
16
|
+
- Raises:
|
|
17
|
+
- `pydantic.ValidationError` if config values violate `MTNCloudConfig` constraints
|
|
18
|
+
|
|
19
|
+
### `whoami() -> User`
|
|
20
|
+
|
|
21
|
+
- Endpoint: `GET /api/whoami`
|
|
22
|
+
- Parameters: none
|
|
23
|
+
- Returns: `User`
|
|
24
|
+
- Raises: common API exceptions
|
|
25
|
+
|
|
26
|
+
### `ping() -> bool`
|
|
27
|
+
|
|
28
|
+
Connectivity/auth convenience check.
|
|
29
|
+
|
|
30
|
+
- Endpoint sequence:
|
|
31
|
+
- `GET /api/whoami` (via `whoami()`)
|
|
32
|
+
- Parameters: none
|
|
33
|
+
- Returns:
|
|
34
|
+
- `True` if request succeeds
|
|
35
|
+
- `False` for any exception
|
|
36
|
+
- Raises: none (exceptions are swallowed and converted to `False`)
|
|
37
|
+
|
|
38
|
+
### `close() -> None`
|
|
39
|
+
|
|
40
|
+
- Endpoint: None
|
|
41
|
+
- Parameters: none
|
|
42
|
+
- Returns: `None`
|
|
43
|
+
- Raises: none
|
|
44
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Resource: `cloud.clouds` (`CloudsResource`)
|
|
2
|
+
|
|
3
|
+
### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, group_id=None, type_code=None, **filters) -> list[Cloud]`
|
|
4
|
+
|
|
5
|
+
- Endpoint: `GET /api/zones`
|
|
6
|
+
- Parameters:
|
|
7
|
+
- Shared list args
|
|
8
|
+
- `name`: cloud/zone name filter
|
|
9
|
+
- `group_id`: mapped to `groupId`
|
|
10
|
+
- `type_code`: mapped to `type` (example: `openstack`)
|
|
11
|
+
- Returns: `list[Cloud]`
|
|
12
|
+
- Raises: common API exceptions
|
|
13
|
+
|
|
14
|
+
### `list_openstack(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, group_id=None, **filters) -> list[Cloud]`
|
|
15
|
+
|
|
16
|
+
- Endpoint: `GET /api/zones?type=openstack`
|
|
17
|
+
- Returns: OpenStack-only clouds
|
|
18
|
+
- Raises: common API exceptions
|
|
19
|
+
|
|
20
|
+
### `get(cloud_id: int) -> Cloud`
|
|
21
|
+
|
|
22
|
+
- Endpoint: `GET /api/zones/{cloud_id}`
|
|
23
|
+
- Returns: `Cloud`
|
|
24
|
+
- Raises: common API exceptions
|
|
25
|
+
|
|
26
|
+
### `get_by_name(name: str) -> Cloud`
|
|
27
|
+
|
|
28
|
+
- Endpoint sequence:
|
|
29
|
+
- `GET /api/zones?name=<name>&max=1`
|
|
30
|
+
- Returns: `Cloud`
|
|
31
|
+
- Raises:
|
|
32
|
+
- common API exceptions
|
|
33
|
+
- `NotFoundError` when no match
|
|
34
|
+
|
|
35
|
+
### `list_by_group(group_id: int) -> list[Cloud]`
|
|
36
|
+
|
|
37
|
+
- Endpoint: `GET /api/zones?groupId=<group_id>`
|
|
38
|
+
- Returns: `list[Cloud]`
|
|
39
|
+
- Raises: common API exceptions
|
|
40
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Resource: `cloud.groups` (`GroupsResource`)
|
|
2
|
+
|
|
3
|
+
### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, **filters) -> list[Group]`
|
|
4
|
+
|
|
5
|
+
- Endpoint: `GET /api/groups`
|
|
6
|
+
- Parameters:
|
|
7
|
+
- Shared list args
|
|
8
|
+
- `name`: group name filter
|
|
9
|
+
- Returns: `list[Group]`
|
|
10
|
+
- Raises: common API exceptions
|
|
11
|
+
|
|
12
|
+
### `get(group_id: int) -> Group`
|
|
13
|
+
|
|
14
|
+
- Endpoint: `GET /api/groups/{group_id}`
|
|
15
|
+
- Returns: `Group`
|
|
16
|
+
- Raises: common API exceptions
|
|
17
|
+
|
|
18
|
+
### `get_by_name(name: str) -> Group`
|
|
19
|
+
|
|
20
|
+
- Endpoint sequence:
|
|
21
|
+
- `GET /api/groups?name=<name>&max=1`
|
|
22
|
+
- Returns: `Group`
|
|
23
|
+
- Raises:
|
|
24
|
+
- common API exceptions
|
|
25
|
+
- `NotFoundError` when no match
|
|
26
|
+
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
This section documents the public SDK surface in endpoint-first format.
|
|
4
|
+
|
|
5
|
+
## Sections
|
|
6
|
+
|
|
7
|
+
- [Client (`MTNCloud`)](./client.md)
|
|
8
|
+
- [Instances (`cloud.instances`)](./instances.md)
|
|
9
|
+
- [Instance Types (`cloud.instance_types`)](./instance-types.md)
|
|
10
|
+
- [Networks (`cloud.networks`)](./networks.md)
|
|
11
|
+
- [Clouds (`cloud.clouds`)](./clouds.md)
|
|
12
|
+
- [Groups (`cloud.groups`)](./groups.md)
|
|
13
|
+
- [Plans (`cloud.plans`)](./plans.md)
|
|
14
|
+
- [Storage Buckets (`cloud.storage_buckets`)](./storage-buckets.md)
|
|
15
|
+
- [Archive Buckets (`cloud.archive_buckets`)](./archive-buckets.md)
|
|
16
|
+
|
|
17
|
+
## Conventions
|
|
18
|
+
|
|
19
|
+
- Base URL: `https://console.cloud.mtn.ng` by default (configurable via `MTN_CLOUD_URL`).
|
|
20
|
+
- API prefix: the SDK automatically appends `/api`.
|
|
21
|
+
- Endpoint examples below are shown as relative API paths, e.g. `GET /api/instances`.
|
|
22
|
+
- All resource managers are accessed from a client instance:
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
from mtn_cloud import MTNCloud
|
|
26
|
+
|
|
27
|
+
cloud = MTNCloud(token="...")
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Common Exceptions
|
|
31
|
+
|
|
32
|
+
All HTTP-backed methods may raise these exceptions based on API response or transport errors:
|
|
33
|
+
|
|
34
|
+
| Exception | When it is raised |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `AuthenticationError` | `401` or missing/invalid credentials |
|
|
37
|
+
| `ForbiddenError` | `403` insufficient permission |
|
|
38
|
+
| `NotFoundError` | `404` resource not found |
|
|
39
|
+
| `ValidationError` | `400` invalid input/payload |
|
|
40
|
+
| `RateLimitError` | `429` too many requests |
|
|
41
|
+
| `ServerError` | `5xx` backend failure |
|
|
42
|
+
| `TimeoutError` | request timeout |
|
|
43
|
+
| `MTNCloudError` | connection errors, unknown status codes, generic request failures |
|
|
44
|
+
|
|
45
|
+
Method-specific local exceptions (for example `FileNotFoundError`) are documented per method.
|
|
46
|
+
|
|
47
|
+
## Shared `list(...)` Query Arguments
|
|
48
|
+
|
|
49
|
+
Most resource managers implement a `list(...)` variant with these common query controls:
|
|
50
|
+
|
|
51
|
+
| Argument | API Query Key | Notes |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| `max_results` | `max` | Maximum returned rows |
|
|
54
|
+
| `offset` | `offset` | Pagination offset |
|
|
55
|
+
| `sort` | `sort` | Sort field |
|
|
56
|
+
| `direction` | `direction` | `asc` or `desc` |
|
|
57
|
+
| `phrase` | `phrase` | API-side search phrase |
|
|
58
|
+
| `**filters` | passthrough | Extra endpoint-specific filters |
|
|
59
|
+
|
|
60
|
+
## Shared Inherited Helper
|
|
61
|
+
|
|
62
|
+
Every resource manager (`instances`, `networks`, `plans`, etc.) inherits:
|
|
63
|
+
|
|
64
|
+
### `resource.exists(resource_id: int) -> bool`
|
|
65
|
+
|
|
66
|
+
- Endpoint sequence:
|
|
67
|
+
- `GET /api/<resource-path>/{resource_id}`
|
|
68
|
+
- Returns:
|
|
69
|
+
- `True` if found
|
|
70
|
+
- `False` only when `NotFoundError` occurs
|
|
71
|
+
- Raises:
|
|
72
|
+
- Any non-`NotFoundError` common API exception
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
## References
|
|
76
|
+
|
|
77
|
+
- MTN Cloud Console: <https://console.cloud.mtn.ng>
|
|
78
|
+
- MTN Cloud Guide: <https://cloud.mtn.ng/documentation>
|
|
79
|
+
- Morpheus API Documentation (supplementary): <https://apidocs.morpheusdata.com/>
|
|
80
|
+
- SDK Source: <https://github.com/mahveotm/mtn-cloud-python>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Resource: `cloud.instance_types` (`InstanceTypesResource`)
|
|
2
|
+
|
|
3
|
+
### `list(max_results=None, offset=0, sort="name", direction="asc", phrase=None, name=None, code=None, category=None, featured=None, **filters) -> list[InstanceType]`
|
|
4
|
+
|
|
5
|
+
- Endpoint: `GET /api/instance-types`
|
|
6
|
+
- Parameters:
|
|
7
|
+
- Shared list args
|
|
8
|
+
- `name`: name filter
|
|
9
|
+
- `code`: code filter
|
|
10
|
+
- `category`: category filter (`os`, `sql`, `web`, `apps`, etc.)
|
|
11
|
+
- `featured`: feature flag filter
|
|
12
|
+
- Returns: `list[InstanceType]`
|
|
13
|
+
- Raises: common API exceptions
|
|
14
|
+
|
|
15
|
+
### `get(instance_type_id: int) -> InstanceType`
|
|
16
|
+
|
|
17
|
+
- Endpoint: `GET /api/instance-types/{instance_type_id}`
|
|
18
|
+
- Returns: `InstanceType`
|
|
19
|
+
- Raises: common API exceptions
|
|
20
|
+
|
|
21
|
+
### `get_by_code(code: str) -> InstanceType`
|
|
22
|
+
|
|
23
|
+
- Endpoint sequence:
|
|
24
|
+
- `GET /api/instance-types?code=<code>&max=1`
|
|
25
|
+
- Returns: `InstanceType`
|
|
26
|
+
- Raises:
|
|
27
|
+
- common API exceptions
|
|
28
|
+
- `NotFoundError` when no match
|
|
29
|
+
|
|
30
|
+
### `get_by_name(name: str) -> InstanceType`
|
|
31
|
+
|
|
32
|
+
- Endpoint sequence:
|
|
33
|
+
- `GET /api/instance-types?name=<name>&max=1`
|
|
34
|
+
- Returns: `InstanceType`
|
|
35
|
+
- Raises:
|
|
36
|
+
- common API exceptions
|
|
37
|
+
- `NotFoundError` when no match
|
|
38
|
+
|
|
39
|
+
### `list_os() -> list[InstanceType]`
|
|
40
|
+
|
|
41
|
+
- Endpoint: `GET /api/instance-types?category=os`
|
|
42
|
+
- Returns: OS instance types
|
|
43
|
+
- Raises: common API exceptions
|
|
44
|
+
|
|
45
|
+
### `list_databases() -> list[InstanceType]`
|
|
46
|
+
|
|
47
|
+
- Endpoint: `GET /api/instance-types?category=sql`
|
|
48
|
+
- Returns: database instance types
|
|
49
|
+
- Raises: common API exceptions
|
|
50
|
+
|
|
51
|
+
### `list_web() -> list[InstanceType]`
|
|
52
|
+
|
|
53
|
+
- Endpoint: `GET /api/instance-types?category=web`
|
|
54
|
+
- Returns: web instance types
|
|
55
|
+
- Raises: common API exceptions
|
|
56
|
+
|
|
57
|
+
### `list_apps() -> list[InstanceType]`
|
|
58
|
+
|
|
59
|
+
- Endpoint: `GET /api/instance-types?category=apps`
|
|
60
|
+
- Returns: app instance types
|
|
61
|
+
- Raises: common API exceptions
|
|
62
|
+
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Resource: `cloud.instances` (`InstancesResource`)
|
|
2
|
+
|
|
3
|
+
### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, status=None, cloud_id=None, group_id=None, labels=None, **filters) -> list[Instance]`
|
|
4
|
+
|
|
5
|
+
- Endpoint: `GET /api/instances`
|
|
6
|
+
- Parameters:
|
|
7
|
+
- Shared list args (see [API Reference](./index.md#shared-list-query-arguments))
|
|
8
|
+
- `name`: exact name filter
|
|
9
|
+
- `status`: status filter
|
|
10
|
+
- `cloud_id`: mapped to query `zoneId`
|
|
11
|
+
- `group_id`: mapped to query `siteId`
|
|
12
|
+
- `labels`: list mapped to comma-delimited query `labels`
|
|
13
|
+
- Returns: `list[Instance]`
|
|
14
|
+
- Raises: common API exceptions
|
|
15
|
+
|
|
16
|
+
### `get(instance_id: int) -> Instance`
|
|
17
|
+
|
|
18
|
+
- Endpoint: `GET /api/instances/{instance_id}`
|
|
19
|
+
- Parameters:
|
|
20
|
+
- `instance_id`: instance numeric ID
|
|
21
|
+
- Returns: `Instance`
|
|
22
|
+
- Raises: common API exceptions
|
|
23
|
+
|
|
24
|
+
### `get_by_name(name: str) -> Instance`
|
|
25
|
+
|
|
26
|
+
- Endpoint sequence:
|
|
27
|
+
- `GET /api/instances?name=<name>&max=1`
|
|
28
|
+
- Parameters:
|
|
29
|
+
- `name`: instance name
|
|
30
|
+
- Returns: `Instance`
|
|
31
|
+
- Raises:
|
|
32
|
+
- common API exceptions
|
|
33
|
+
- `NotFoundError` when no instance matches
|
|
34
|
+
|
|
35
|
+
### `create(name: str, *, cloud: str, type: str, group: str, layout: int, plan: int, description=None, environment=None, labels=None, tags=None, copies=1, layout_size=1, resource_pool_id=None, 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
|
+
|
|
37
|
+
- Endpoint sequence:
|
|
38
|
+
- `GET /api/groups?name=<group>&max=1` (resolve group name to `group_id`)
|
|
39
|
+
- `POST /api/instances`
|
|
40
|
+
- Parameters:
|
|
41
|
+
- Required core fields:
|
|
42
|
+
- `name`: new instance name
|
|
43
|
+
- `cloud`: cloud/zone name (example: `MTNNG_CLOUD_AZ_1`)
|
|
44
|
+
- `type`: instance type code (example: `MTN-CS10`)
|
|
45
|
+
- `group`: group/site name (resolved to ID)
|
|
46
|
+
- `layout`: layout ID
|
|
47
|
+
- `plan`: service plan ID
|
|
48
|
+
- Optional metadata:
|
|
49
|
+
- `description`, `environment`, `labels`, `tags`
|
|
50
|
+
- Optional sizing/provisioning:
|
|
51
|
+
- `copies`, `layout_size`
|
|
52
|
+
- Optional MTN/OpenStack-specific provisioning:
|
|
53
|
+
- `resource_pool_id`, `availability_zone`, `security_group`, `os_external_network_id`, `create_user`
|
|
54
|
+
- Optional automation:
|
|
55
|
+
- `workflow_id`, `shutdown_days`, `expire_days`, `create_backup`
|
|
56
|
+
- Optional networking/storage details:
|
|
57
|
+
- `security_groups`, `ports`, `volumes`, `network_interfaces`, `options`
|
|
58
|
+
- Returns: `Instance`
|
|
59
|
+
- Raises:
|
|
60
|
+
- common API exceptions
|
|
61
|
+
- `NotFoundError` when `group` cannot be resolved
|
|
62
|
+
|
|
63
|
+
### `update(instance_id: int, name=None, description=None, labels=None) -> Instance`
|
|
64
|
+
|
|
65
|
+
- Endpoint: `PUT /api/instances/{instance_id}`
|
|
66
|
+
- Parameters:
|
|
67
|
+
- `instance_id`: target instance ID
|
|
68
|
+
- `name`: replacement name
|
|
69
|
+
- `description`: replacement description
|
|
70
|
+
- `labels`: replacement labels list
|
|
71
|
+
- Returns: `Instance`
|
|
72
|
+
- Raises: common API exceptions
|
|
73
|
+
|
|
74
|
+
### `delete(instance_id: int, preserve_volumes=False, force=False) -> bool`
|
|
75
|
+
|
|
76
|
+
- Endpoint: `DELETE /api/instances/{instance_id}`
|
|
77
|
+
- Parameters:
|
|
78
|
+
- `instance_id`: target instance ID
|
|
79
|
+
- `preserve_volumes`: adds query `preserveVolumes=on`
|
|
80
|
+
- `force`: adds query `force=on`
|
|
81
|
+
- Returns: `True` on successful deletion request
|
|
82
|
+
- Raises: common API exceptions
|
|
83
|
+
|
|
84
|
+
### `start(instance_id: int) -> Instance`
|
|
85
|
+
|
|
86
|
+
- Endpoint sequence:
|
|
87
|
+
- `PUT /api/instances/{instance_id}/start`
|
|
88
|
+
- `GET /api/instances/{instance_id}`
|
|
89
|
+
- Returns: refreshed `Instance`
|
|
90
|
+
- Raises: common API exceptions
|
|
91
|
+
|
|
92
|
+
### `stop(instance_id: int) -> Instance`
|
|
93
|
+
|
|
94
|
+
- Endpoint sequence:
|
|
95
|
+
- `PUT /api/instances/{instance_id}/stop`
|
|
96
|
+
- `GET /api/instances/{instance_id}`
|
|
97
|
+
- Returns: refreshed `Instance`
|
|
98
|
+
- Raises: common API exceptions
|
|
99
|
+
|
|
100
|
+
### `restart(instance_id: int) -> Instance`
|
|
101
|
+
|
|
102
|
+
- Endpoint sequence:
|
|
103
|
+
- `PUT /api/instances/{instance_id}/restart`
|
|
104
|
+
- `GET /api/instances/{instance_id}`
|
|
105
|
+
- Returns: refreshed `Instance`
|
|
106
|
+
- Raises: common API exceptions
|
|
107
|
+
|
|
108
|
+
### `suspend(instance_id: int) -> Instance`
|
|
109
|
+
|
|
110
|
+
- Endpoint sequence:
|
|
111
|
+
- `PUT /api/instances/{instance_id}/suspend`
|
|
112
|
+
- `GET /api/instances/{instance_id}`
|
|
113
|
+
- Returns: refreshed `Instance`
|
|
114
|
+
- Raises: common API exceptions
|
|
115
|
+
|
|
116
|
+
### `resize(instance_id: int, plan_id: int) -> Instance`
|
|
117
|
+
|
|
118
|
+
- Endpoint sequence:
|
|
119
|
+
- `PUT /api/instances/{instance_id}/resize`
|
|
120
|
+
- `GET /api/instances/{instance_id}`
|
|
121
|
+
- Parameters:
|
|
122
|
+
- `plan_id`: new service plan ID
|
|
123
|
+
- Returns: resized `Instance`
|
|
124
|
+
- Raises: common API exceptions
|
|
125
|
+
|
|
126
|
+
### `wait_for_status(instance_id: int, target_status: str, timeout: int = 300, poll_interval: int = 5) -> Instance`
|
|
127
|
+
|
|
128
|
+
Client-side polling helper.
|
|
129
|
+
|
|
130
|
+
- Endpoint sequence:
|
|
131
|
+
- repeated `GET /api/instances/{instance_id}` until target status or timeout
|
|
132
|
+
- Parameters:
|
|
133
|
+
- `target_status`: desired status string (`running`, `stopped`, etc.)
|
|
134
|
+
- `timeout`: max wait in seconds
|
|
135
|
+
- `poll_interval`: sleep interval between polls
|
|
136
|
+
- Returns: `Instance` once target status matches
|
|
137
|
+
- Raises:
|
|
138
|
+
- common API exceptions from internal `get`
|
|
139
|
+
- `TimeoutError` when timeout is exceeded
|
|
140
|
+
- `RuntimeError` if instance enters `failed` state
|
|
141
|
+
|
|
142
|
+
### `wait_until_running(instance_id: int, timeout: int = 300) -> Instance`
|
|
143
|
+
|
|
144
|
+
- Endpoint behavior: same as `wait_for_status(..., target_status="running")`
|
|
145
|
+
- Returns: `Instance`
|
|
146
|
+
- Raises: same as `wait_for_status`
|
|
147
|
+
|
|
148
|
+
### `wait_until_stopped(instance_id: int, timeout: int = 300) -> Instance`
|
|
149
|
+
|
|
150
|
+
- Endpoint behavior: same as `wait_for_status(..., target_status="stopped")`
|
|
151
|
+
- Returns: `Instance`
|
|
152
|
+
- Raises: same as `wait_for_status`
|
|
153
|
+
|
|
154
|
+
### `get_console(instance_id: int) -> dict[str, Any]`
|
|
155
|
+
|
|
156
|
+
- Endpoint: `GET /api/instances/{instance_id}/console`
|
|
157
|
+
- Returns: raw console payload (`url`, credentials, metadata)
|
|
158
|
+
- Raises: common API exceptions
|
|
159
|
+
|
|
160
|
+
### `get_history(instance_id: int, max_results: int | None = None) -> list[dict[str, Any]]`
|
|
161
|
+
|
|
162
|
+
- Endpoint: `GET /api/instances/{instance_id}/history`
|
|
163
|
+
- Parameters:
|
|
164
|
+
- `max_results`: maps to query `max`
|
|
165
|
+
- Returns: list from response key `processes`
|
|
166
|
+
- Raises: common API exceptions
|
|
167
|
+
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Resource: `cloud.networks` (`NetworksResource`)
|
|
2
|
+
|
|
3
|
+
### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, cloud_id=None, **filters) -> list[Network]`
|
|
4
|
+
|
|
5
|
+
- Endpoint: `GET /api/networks`
|
|
6
|
+
- Parameters:
|
|
7
|
+
- Shared list args
|
|
8
|
+
- `name`: network name filter
|
|
9
|
+
- `cloud_id`: mapped to query `zoneId`
|
|
10
|
+
- Returns: `list[Network]`
|
|
11
|
+
- Raises: common API exceptions
|
|
12
|
+
|
|
13
|
+
### `get(network_id: int) -> Network`
|
|
14
|
+
|
|
15
|
+
- Endpoint: `GET /api/networks/{network_id}`
|
|
16
|
+
- Returns: `Network`
|
|
17
|
+
- Raises: common API exceptions
|
|
18
|
+
|
|
19
|
+
### `get_by_name(name: str, cloud_id: int | None = None) -> Network`
|
|
20
|
+
|
|
21
|
+
- Endpoint sequence:
|
|
22
|
+
- `GET /api/networks?name=<name>&max=1`
|
|
23
|
+
- Adds `zoneId=<cloud_id>` when provided
|
|
24
|
+
- Returns: `Network`
|
|
25
|
+
- Raises:
|
|
26
|
+
- common API exceptions
|
|
27
|
+
- `NotFoundError` when no match
|
|
28
|
+
|
|
29
|
+
### `list_by_cloud(cloud_id: int) -> list[Network]`
|
|
30
|
+
|
|
31
|
+
- Endpoint: `GET /api/networks?zoneId=<cloud_id>`
|
|
32
|
+
- Returns: `list[Network]`
|
|
33
|
+
- Raises: common API exceptions
|
|
34
|
+
|
|
35
|
+
### `create(name: str, *, cloud_id: int, group_id: int, type_id=None, display_name=None, labels=None, description=None, cidr=None, gateway=None, dns_primary=None, dns_secondary=None, vlan_id=None, switch_id=None, pool_id=None, allow_static_override=None, assign_public_ip=None, active=None, dhcp_server=None, network_domain_id=None, search_domains=None, network_proxy_id=None, appliance_url_proxy_bypass=None, no_proxy=None, visibility=None, tenant_ids=None, resource_permission_all=None, resource_permission_site_ids=None) -> Network`
|
|
36
|
+
|
|
37
|
+
- Endpoint: `POST /api/networks`
|
|
38
|
+
- Parameters:
|
|
39
|
+
- Required:
|
|
40
|
+
- `name`: network name
|
|
41
|
+
- `cloud_id`: cloud/zone ID
|
|
42
|
+
- `group_id`: group/site ID
|
|
43
|
+
- Common optional network config:
|
|
44
|
+
- `type_id`, `display_name`, `labels`, `description`, `cidr`, `gateway`
|
|
45
|
+
- `dns_primary`, `dns_secondary`, `vlan_id`, `switch_id`, `pool_id`
|
|
46
|
+
- `allow_static_override`, `assign_public_ip`, `active`, `dhcp_server`
|
|
47
|
+
- `network_domain_id`, `search_domains`, `network_proxy_id`
|
|
48
|
+
- `appliance_url_proxy_bypass`, `no_proxy`, `visibility`
|
|
49
|
+
- `tenant_ids`, `resource_permission_all`, `resource_permission_site_ids`
|
|
50
|
+
- Returns: `Network`
|
|
51
|
+
- Raises: common API exceptions
|
|
52
|
+
|
|
53
|
+
### `update(network_id: int, *, display_name=None, labels=None, description=None, cidr=None, gateway=None, dns_primary=None, dns_secondary=None, vlan_id=None, switch_id=None, pool_id=None, allow_static_override=None, assign_public_ip=None, active=None, dhcp_server=None, network_domain_id=None, search_domains=None, network_proxy_id=None, appliance_url_proxy_bypass=None, no_proxy=None, visibility=None, tenant_ids=None, resource_permission_all=None, resource_permission_site_ids=None) -> Network`
|
|
54
|
+
|
|
55
|
+
- Endpoint: `PUT /api/networks/{network_id}`
|
|
56
|
+
- Parameters:
|
|
57
|
+
- `network_id`: target network ID
|
|
58
|
+
- Optional fields mirror `create(...)` (except required create-only identifiers)
|
|
59
|
+
- Returns: `Network`
|
|
60
|
+
- Raises: common API exceptions
|
|
61
|
+
|
|
62
|
+
### `delete(network_id: int) -> bool`
|
|
63
|
+
|
|
64
|
+
- Endpoint: `DELETE /api/networks/{network_id}`
|
|
65
|
+
- Returns: `True`
|
|
66
|
+
- Raises: common API exceptions
|
|
67
|
+
|
|
68
|
+
### `list_subnets(network_id: int) -> list[Subnet]`
|
|
69
|
+
|
|
70
|
+
- Endpoint: `GET /api/networks/{network_id}/subnets`
|
|
71
|
+
- Returns: `list[Subnet]`
|
|
72
|
+
- Raises: common API exceptions
|
|
73
|
+
|
|
74
|
+
### `list_types(name=None, code=None, phrase=None, openstack_only=False) -> list[NetworkTypeInfo]`
|
|
75
|
+
|
|
76
|
+
- Endpoint: `GET /api/network-types`
|
|
77
|
+
- Parameters:
|
|
78
|
+
- `name`: exact name filter
|
|
79
|
+
- `code`: exact code filter
|
|
80
|
+
- `phrase`: phrase filter
|
|
81
|
+
- `openstack_only`: client-side filter on returned `is_openstack`
|
|
82
|
+
- Returns: `list[NetworkTypeInfo]`
|
|
83
|
+
- Raises: common API exceptions
|
|
84
|
+
|
|
85
|
+
### `get_type(type_id: int) -> NetworkTypeInfo`
|
|
86
|
+
|
|
87
|
+
- Endpoint: `GET /api/network-types/{type_id}`
|
|
88
|
+
- Returns: `NetworkTypeInfo`
|
|
89
|
+
- Raises: common API exceptions
|
|
90
|
+
|
|
91
|
+
### `list_floating_ips(*, phrase=None, ip_address=None, ip_status=None, cloud_id=None, server_id=None) -> list[NetworkFloatingIP]`
|
|
92
|
+
|
|
93
|
+
- Endpoint: `GET /api/networks/floating-ips`
|
|
94
|
+
- Parameters:
|
|
95
|
+
- `phrase`: search phrase
|
|
96
|
+
- `ip_address`: exact IP match
|
|
97
|
+
- `ip_status`: provider status value
|
|
98
|
+
- `cloud_id`: mapped to `zoneId`
|
|
99
|
+
- `server_id`: mapped to `serverId`
|
|
100
|
+
- Returns: `list[NetworkFloatingIP]`
|
|
101
|
+
- Raises: common API exceptions
|
|
102
|
+
|
|
103
|
+
### `get_floating_ip(floating_ip_id: int) -> NetworkFloatingIP`
|
|
104
|
+
|
|
105
|
+
- Endpoint: `GET /api/networks/floating-ips/{floating_ip_id}`
|
|
106
|
+
- Returns: `NetworkFloatingIP`
|
|
107
|
+
- Raises: common API exceptions
|
|
108
|
+
|
|
109
|
+
### `allocate_floating_ip(*, network_server_id: int, floating_ip_pool_id: int) -> NetworkFloatingIP`
|
|
110
|
+
|
|
111
|
+
- Endpoint: `POST /api/networks/floating-ips`
|
|
112
|
+
- Parameters:
|
|
113
|
+
- `network_server_id`: backend network server ID
|
|
114
|
+
- `floating_ip_pool_id`: floating IP pool ID
|
|
115
|
+
- Returns: `NetworkFloatingIP`
|
|
116
|
+
- Raises: common API exceptions
|
|
117
|
+
|
|
118
|
+
### `release_floating_ip(floating_ip_id: int) -> bool`
|
|
119
|
+
|
|
120
|
+
- Endpoint: `PUT /api/networks/floating-ips/{floating_ip_id}/release`
|
|
121
|
+
- Returns: `True`
|
|
122
|
+
- Raises: common API exceptions
|
|
123
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Resource: `cloud.plans` (`PlansResource`)
|
|
2
|
+
|
|
3
|
+
### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, **filters) -> list[ServicePlan]`
|
|
4
|
+
|
|
5
|
+
- Endpoint: `GET /api/service-plans`
|
|
6
|
+
- Parameters:
|
|
7
|
+
- Shared list args
|
|
8
|
+
- `name`: plan name filter
|
|
9
|
+
- Returns: `list[ServicePlan]`
|
|
10
|
+
- Raises: common API exceptions
|
|
11
|
+
|
|
12
|
+
### `get(plan_id: int) -> ServicePlan`
|
|
13
|
+
|
|
14
|
+
- Endpoint: `GET /api/service-plans/{plan_id}`
|
|
15
|
+
- Returns: `ServicePlan`
|
|
16
|
+
- Raises: common API exceptions
|
|
17
|
+
|
|
18
|
+
### `get_by_name(name: str) -> ServicePlan`
|
|
19
|
+
|
|
20
|
+
- Endpoint sequence:
|
|
21
|
+
- `GET /api/service-plans?name=<name>&max=1`
|
|
22
|
+
- Returns: `ServicePlan`
|
|
23
|
+
- Raises:
|
|
24
|
+
- common API exceptions
|
|
25
|
+
- `NotFoundError` when no match
|
|
26
|
+
|
|
27
|
+
### `find(cores=None, memory_gb=None, storage_gb=None) -> ServicePlan | None`
|
|
28
|
+
|
|
29
|
+
Client-side selector for first plan meeting minimum requirements.
|
|
30
|
+
|
|
31
|
+
- Endpoint sequence:
|
|
32
|
+
- `GET /api/service-plans`
|
|
33
|
+
- Parameters:
|
|
34
|
+
- `cores`: minimum CPU cores
|
|
35
|
+
- `memory_gb`: minimum memory in GB
|
|
36
|
+
- `storage_gb`: minimum storage in GB
|
|
37
|
+
- Returns:
|
|
38
|
+
- `ServicePlan` first match
|
|
39
|
+
- `None` if no plan satisfies constraints
|
|
40
|
+
- Raises: common API exceptions
|
|
41
|
+
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Resource: `cloud.storage_buckets` (`StorageBucketsResource`)
|
|
2
|
+
|
|
3
|
+
### `list(max_results=None, offset=0, sort=None, direction=None, phrase=None, name=None, **filters) -> list[StorageBucket]`
|
|
4
|
+
|
|
5
|
+
- Endpoint: `GET /api/storage-buckets`
|
|
6
|
+
- Parameters:
|
|
7
|
+
- Shared list args
|
|
8
|
+
- `name`: storage bucket name filter
|
|
9
|
+
- Returns: `list[StorageBucket]`
|
|
10
|
+
- Raises: common API exceptions
|
|
11
|
+
|
|
12
|
+
### `get(storage_bucket_id: int) -> StorageBucket`
|
|
13
|
+
|
|
14
|
+
- Endpoint: `GET /api/storage-buckets/{storage_bucket_id}`
|
|
15
|
+
- Returns: `StorageBucket`
|
|
16
|
+
- Raises: common API exceptions
|
|
17
|
+
|
|
18
|
+
### `get_by_name(name: str) -> StorageBucket`
|
|
19
|
+
|
|
20
|
+
- Endpoint sequence:
|
|
21
|
+
- `GET /api/storage-buckets?name=<name>&max=1`
|
|
22
|
+
- Returns: `StorageBucket`
|
|
23
|
+
- Raises:
|
|
24
|
+
- common API exceptions
|
|
25
|
+
- `NotFoundError` when no match
|
|
26
|
+
|
|
27
|
+
### `create(name: str, *, bucket_name: str, access_key: str, secret_key: str, endpoint: str, storage_server=None, default_backup_target=None, copy_to_store=None, default_deployment_target=None, default_virtual_image_target=None, retention_policy_type="none", retention_policy_days=None, retention_provider=None, create_bucket=True) -> StorageBucket`
|
|
28
|
+
|
|
29
|
+
- Endpoint: `POST /api/storage-buckets`
|
|
30
|
+
- Parameters:
|
|
31
|
+
- Required:
|
|
32
|
+
- `name`: storage bucket object name
|
|
33
|
+
- `bucket_name`: underlying S3 bucket/container name
|
|
34
|
+
- `access_key`, `secret_key`, `endpoint`: provider credentials/endpoint
|
|
35
|
+
- Optional target/default flags:
|
|
36
|
+
- `default_backup_target`, `copy_to_store`, `default_deployment_target`, `default_virtual_image_target`
|
|
37
|
+
- Optional retention behavior:
|
|
38
|
+
- `retention_policy_type`: `backup`, `delete`, or `none`
|
|
39
|
+
- `retention_policy_days`, `retention_provider`
|
|
40
|
+
- `storage_server`: optional storage server ID
|
|
41
|
+
- `create_bucket`: create target bucket when missing
|
|
42
|
+
- Returns: `StorageBucket`
|
|
43
|
+
- Raises: common API exceptions
|
|
44
|
+
|
|
45
|
+
### `create_s3(name: str, *, bucket_name: str, access_key: str, secret_key: str, endpoint: str, storage_server=None, create_bucket=True, default_backup_target=None, copy_to_store=None, default_deployment_target=None, default_virtual_image_target=None) -> StorageBucket`
|
|
46
|
+
|
|
47
|
+
Convenience wrapper for S3-backed create.
|
|
48
|
+
|
|
49
|
+
- Endpoint behavior: forwards to `create(...)` then `POST /api/storage-buckets`
|
|
50
|
+
- Returns: `StorageBucket`
|
|
51
|
+
- Raises: same as `create`
|
|
52
|
+
|
|
53
|
+
### `update(storage_bucket_id: int, *, name=None, bucket_name=None, config=None, default_backup_target=None, copy_to_store=None, default_deployment_target=None, default_virtual_image_target=None, retention_policy_type=None, retention_policy_days=None, retention_provider=None, create_bucket=None) -> StorageBucket`
|
|
54
|
+
|
|
55
|
+
- Endpoint: `PUT /api/storage-buckets/{storage_bucket_id}`
|
|
56
|
+
- Parameters:
|
|
57
|
+
- `storage_bucket_id`: target ID
|
|
58
|
+
- Optional updates for name/bucket/config/defaults/retention
|
|
59
|
+
- Returns: `StorageBucket`
|
|
60
|
+
- Raises: common API exceptions
|
|
61
|
+
|
|
62
|
+
### `delete(storage_bucket_id: int, *, remove_resources: bool = False) -> bool`
|
|
63
|
+
|
|
64
|
+
- Endpoint: `DELETE /api/storage-buckets/{storage_bucket_id}`
|
|
65
|
+
- Parameters:
|
|
66
|
+
- `remove_resources`: when `True`, sends `removeResources=true`
|
|
67
|
+
- Returns: `True`
|
|
68
|
+
- Raises: common API exceptions
|
|
69
|
+
|
|
@@ -14,7 +14,8 @@ Use this guide in two ways:
|
|
|
14
14
|
4. [Storage](./storage.md)
|
|
15
15
|
5. [Advanced Cookbook](./advanced-cookbook.md)
|
|
16
16
|
6. [API Overview](./api-overview.md)
|
|
17
|
-
7. [
|
|
17
|
+
7. [API Reference](./api-reference/index.md)
|
|
18
|
+
8. [Docstring Style Standard](./docstring-style.md)
|
|
18
19
|
|
|
19
20
|
## Who This Is For
|
|
20
21
|
|
|
@@ -25,7 +26,7 @@ Use this guide in two ways:
|
|
|
25
26
|
## Conventions Used
|
|
26
27
|
|
|
27
28
|
- `cloud` means an initialized `MTNCloud` client.
|
|
28
|
-
- `group` maps to
|
|
29
|
+
- `group` maps to MTN Cloud site.
|
|
29
30
|
- `cloud` or `zone` may be used interchangeably based on Morpheus API naming.
|
|
30
31
|
- Example IDs and codes are illustrative; query your account first before provisioning.
|
|
31
32
|
|
|
@@ -36,4 +37,5 @@ Use this guide in two ways:
|
|
|
36
37
|
3. Networking
|
|
37
38
|
4. Storage
|
|
38
39
|
5. API Overview
|
|
39
|
-
6.
|
|
40
|
+
6. API Reference
|
|
41
|
+
7. Advanced Cookbook
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--md-primary-fg-color: #005f73;
|
|
3
|
+
--md-primary-fg-color--light: #0a9396;
|
|
4
|
+
--md-primary-fg-color--dark: #004a59;
|
|
5
|
+
--md-accent-fg-color: #ee9b00;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
[data-md-color-scheme="default"] {
|
|
9
|
+
--md-code-bg-color: #f3f5f7;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
[data-md-color-scheme="slate"] {
|
|
13
|
+
--md-default-bg-color: #0e1116;
|
|
14
|
+
--md-default-fg-color: #e6edf3;
|
|
15
|
+
--md-code-bg-color: #161b22;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.md-typeset h1 {
|
|
19
|
+
font-weight: 700;
|
|
20
|
+
letter-spacing: -0.01em;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.md-typeset h2 {
|
|
24
|
+
border-bottom: 1px solid var(--md-default-fg-color--lightest);
|
|
25
|
+
padding-bottom: 0.2rem;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.md-typeset code {
|
|
29
|
+
border-radius: 0.25rem;
|
|
30
|
+
}
|
|
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mtn-cloud"
|
|
7
7
|
dynamic = ["version"]
|
|
8
|
-
description = "Community Python SDK for MTN Cloud
|
|
8
|
+
description = "Community Python SDK for MTN Cloud - Deploy and manage cloud resources with ease"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
11
11
|
authors = [
|
|
@@ -17,7 +17,7 @@ maintainers = [
|
|
|
17
17
|
keywords = [
|
|
18
18
|
"mtn",
|
|
19
19
|
"cloud",
|
|
20
|
-
"
|
|
20
|
+
"mtn-cloud",
|
|
21
21
|
"sdk",
|
|
22
22
|
"api",
|
|
23
23
|
"infrastructure",
|
|
@@ -17,7 +17,7 @@ from mtn_cloud.resources.storage_buckets import StorageBucketsResource
|
|
|
17
17
|
|
|
18
18
|
class MTNCloud:
|
|
19
19
|
"""
|
|
20
|
-
MTN Cloud client for interacting with the
|
|
20
|
+
MTN Cloud client for interacting with the MTN Cloud API.
|
|
21
21
|
|
|
22
22
|
This is the main entry point for the SDK. Initialize with your
|
|
23
23
|
API token or credentials to start making API calls.
|
|
@@ -21,12 +21,12 @@ SAMPLE_ARCHIVE_BUCKET = {
|
|
|
21
21
|
"name": "apitestmybucket",
|
|
22
22
|
"description": "API Test: My Archive Bucket",
|
|
23
23
|
"storageProvider": {"id": 113, "name": "Local Archives"},
|
|
24
|
-
"owner": {"id": 1, "name": "
|
|
24
|
+
"owner": {"id": 1, "name": "MTN QA"},
|
|
25
25
|
"createdBy": {"username": "apiuser"},
|
|
26
26
|
"isPublic": False,
|
|
27
27
|
"visibility": "private",
|
|
28
28
|
"code": "64d94943f108",
|
|
29
|
-
"filePath": "
|
|
29
|
+
"filePath": "mtn-archives/64d94943f108/",
|
|
30
30
|
"rawSize": 0,
|
|
31
31
|
"fileCount": 0,
|
|
32
32
|
"accounts": [],
|
|
@@ -35,7 +35,7 @@ SAMPLE_ARCHIVE_BUCKET = {
|
|
|
35
35
|
SAMPLE_ARCHIVE_FILE = {
|
|
36
36
|
"id": 5338,
|
|
37
37
|
"name": "test.txt",
|
|
38
|
-
"filePath": "
|
|
38
|
+
"filePath": "mtn-archives/6f657af7bc7b/test.txt",
|
|
39
39
|
"archiveBucket": {"id": 1115, "name": "apitestmybucket", "isPublic": False},
|
|
40
40
|
"createdBy": {"username": "apiuser"},
|
|
41
41
|
"isDirectory": False,
|
|
@@ -36,21 +36,21 @@ SAMPLE_INSTANCE_TYPE = {
|
|
|
36
36
|
|
|
37
37
|
SAMPLE_INSTANCE_TYPE_MULTIPLE_LAYOUTS = {
|
|
38
38
|
"id": 113,
|
|
39
|
-
"name": "
|
|
40
|
-
"code": "
|
|
39
|
+
"name": "MTN Builds",
|
|
40
|
+
"code": "mtnbuilds",
|
|
41
41
|
"description": None,
|
|
42
42
|
"labels": [],
|
|
43
43
|
"provisionTypeCode": "mixed",
|
|
44
44
|
"category": "web",
|
|
45
45
|
"active": True,
|
|
46
|
-
"environmentPrefix": "
|
|
46
|
+
"environmentPrefix": "MTN_BUILDS",
|
|
47
47
|
"visibility": "private",
|
|
48
48
|
"featured": True,
|
|
49
49
|
"versions": ["7.9-v1", "8.3-v1"],
|
|
50
50
|
"instanceTypeLayouts": [
|
|
51
|
-
{"id": 1313, "name": "
|
|
52
|
-
{"id": 1315, "name": "
|
|
53
|
-
{"id": 1312, "name": "
|
|
51
|
+
{"id": 1313, "name": "MTN Debian", "provisionTypeCode": "vmware"},
|
|
52
|
+
{"id": 1315, "name": "MTN Ubuntu", "provisionTypeCode": "vmware"},
|
|
53
|
+
{"id": 1312, "name": "MTN CentOS", "provisionTypeCode": "vmware"},
|
|
54
54
|
],
|
|
55
55
|
"account": {"id": 1, "name": "mastertenant"},
|
|
56
56
|
}
|
|
@@ -183,7 +183,7 @@ class TestInstanceTypeModel:
|
|
|
183
183
|
"""Test getting layout by name."""
|
|
184
184
|
it = InstanceType.model_validate(SAMPLE_INSTANCE_TYPE_MULTIPLE_LAYOUTS)
|
|
185
185
|
|
|
186
|
-
layout = it.get_layout_by_name("
|
|
186
|
+
layout = it.get_layout_by_name("MTN Ubuntu")
|
|
187
187
|
assert layout is not None
|
|
188
188
|
assert layout.id == 1315
|
|
189
189
|
|
|
@@ -197,7 +197,7 @@ class TestInstanceTypeModel:
|
|
|
197
197
|
|
|
198
198
|
layout = it.get_layout_by_id(1312)
|
|
199
199
|
assert layout is not None
|
|
200
|
-
assert layout.name == "
|
|
200
|
+
assert layout.name == "MTN CentOS"
|
|
201
201
|
|
|
202
202
|
# Test not found
|
|
203
203
|
not_found = it.get_layout_by_id(99999)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|