|
3 | 3 | from dataclasses import dataclass |
4 | 4 | from typing import Literal |
5 | 5 |
|
6 | | -from dataclasses_json import dataclass_json |
| 6 | +from dataclasses_json import Undefined, dataclass_json |
7 | 7 |
|
8 | 8 | from verda.constants import InstanceStatus, Locations |
9 | 9 |
|
10 | 10 | INSTANCES_ENDPOINT = '/instances' |
11 | 11 |
|
12 | 12 | Contract = Literal['LONG_TERM', 'PAY_AS_YOU_GO', 'SPOT'] |
13 | 13 | Pricing = Literal['DYNAMIC_PRICE', 'FIXED_PRICE'] |
| 14 | +OnSpotDiscontinue = Literal['keep_detached', 'move_to_trash', 'delete_permanently'] |
| 15 | + |
| 16 | + |
| 17 | +@dataclass_json(undefined=Undefined.EXCLUDE) |
| 18 | +@dataclass |
| 19 | +class OSVolume: |
| 20 | + """Represents an operating system volume. |
| 21 | +
|
| 22 | + Attributes: |
| 23 | + name: Name of the volume. |
| 24 | + size: Size of the volume in GB. |
| 25 | + on_spot_discontinue: What to do with the volume on spot discontinue. |
| 26 | + - keep_detached: Keep the volume detached. |
| 27 | + - move_to_trash: Move the volume to trash. |
| 28 | + - delete_permanently: Delete the volume permanently. |
| 29 | + Defaults to keep_detached. |
| 30 | + """ |
| 31 | + |
| 32 | + name: str |
| 33 | + size: int |
| 34 | + on_spot_discontinue: OnSpotDiscontinue | None = None |
14 | 35 |
|
15 | 36 |
|
16 | 37 | @dataclass_json |
@@ -123,7 +144,7 @@ def create( |
123 | 144 | startup_script_id: str | None = None, |
124 | 145 | volumes: list[dict] | None = None, |
125 | 146 | existing_volumes: list[str] | None = None, |
126 | | - os_volume: dict | None = None, |
| 147 | + os_volume: OSVolume | dict | None = None, |
127 | 148 | is_spot: bool = False, |
128 | 149 | contract: Contract | None = None, |
129 | 150 | pricing: Pricing | None = None, |
@@ -170,7 +191,7 @@ def create( |
170 | 191 | 'hostname': hostname, |
171 | 192 | 'description': description, |
172 | 193 | 'location_code': location, |
173 | | - 'os_volume': os_volume, |
| 194 | + 'os_volume': os_volume.to_dict() if isinstance(os_volume, OSVolume) else os_volume, |
174 | 195 | 'volumes': volumes or [], |
175 | 196 | 'existing_volumes': existing_volumes or [], |
176 | 197 | 'is_spot': is_spot, |
@@ -204,21 +225,32 @@ def action( |
204 | 225 | id_list: list[str] | str, |
205 | 226 | action: str, |
206 | 227 | volume_ids: list[str] | None = None, |
| 228 | + delete_permanently: bool = False, |
207 | 229 | ) -> None: |
208 | 230 | """Performs an action on one or more instances. |
209 | 231 |
|
210 | 232 | Args: |
211 | 233 | id_list: Single instance ID or list of instance IDs to act upon. |
212 | 234 | action: Action to perform on the instances. |
213 | 235 | volume_ids: Optional list of volume IDs to delete. |
| 236 | + delete_permanently: When deleting (or discontinuing), delete the |
| 237 | + given volume IDs permanently. Only applicable when volume_ids |
| 238 | + is also provided. |
214 | 239 |
|
215 | 240 | Raises: |
216 | 241 | HTTPError: If the action fails or other API error occurs. |
217 | 242 | """ |
218 | 243 | if type(id_list) is str: |
219 | 244 | id_list = [id_list] |
220 | 245 |
|
221 | | - payload = {'id': id_list, 'action': action, 'volume_ids': volume_ids} |
| 246 | + payload = { |
| 247 | + 'id': id_list, |
| 248 | + 'action': action, |
| 249 | + 'volume_ids': volume_ids, |
| 250 | + } |
| 251 | + |
| 252 | + if delete_permanently: |
| 253 | + payload['delete_permanently'] = True |
222 | 254 |
|
223 | 255 | self._http_client.put(INSTANCES_ENDPOINT, json=payload) |
224 | 256 | return |
|
0 commit comments