twc-cli 1.1.0__py3-none-any.whl → 1.3.0__py3-none-any.whl
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.
Potentially problematic release.
This version of twc-cli might be problematic. Click here for more details.
- CHANGELOG.md +48 -15
- twc/__main__.py +72 -1
- twc/__version__.py +1 -1
- twc/api/client.py +319 -2
- twc/click_ext.py +34 -0
- twc/commands/__init__.py +10 -43
- twc/commands/config.py +141 -22
- twc/commands/database.py +633 -0
- twc/commands/image.py +2 -2
- twc/commands/project.py +9 -0
- twc/commands/server.py +89 -47
- twc/commands/storage.py +818 -0
- twc/fmt.py +14 -1
- twc/utils.py +20 -0
- twc/vars.py +20 -0
- {twc_cli-1.1.0.dist-info → twc_cli-1.3.0.dist-info}/METADATA +2 -1
- twc_cli-1.3.0.dist-info/RECORD +26 -0
- {twc_cli-1.1.0.dist-info → twc_cli-1.3.0.dist-info}/WHEEL +1 -1
- twc_cli-1.1.0.dist-info/RECORD +0 -21
- {twc_cli-1.1.0.dist-info → twc_cli-1.3.0.dist-info}/COPYING +0 -0
- {twc_cli-1.1.0.dist-info → twc_cli-1.3.0.dist-info}/entry_points.txt +0 -0
twc/commands/server.py
CHANGED
|
@@ -4,24 +4,27 @@ import re
|
|
|
4
4
|
import os
|
|
5
5
|
import sys
|
|
6
6
|
import datetime
|
|
7
|
+
import webbrowser
|
|
7
8
|
|
|
8
9
|
import click
|
|
9
10
|
from click_aliases import ClickAliasedGroup
|
|
10
11
|
|
|
11
12
|
from twc import fmt
|
|
13
|
+
from twc.click_ext import MutuallyExclusiveOption
|
|
14
|
+
from twc.vars import (
|
|
15
|
+
DEFAULT_CONFIGURATOR_ID,
|
|
16
|
+
REGIONS_WITH_CONFIGURATOR,
|
|
17
|
+
REGIONS_WITH_IPV6,
|
|
18
|
+
TWC_CP_URL,
|
|
19
|
+
)
|
|
12
20
|
from . import (
|
|
13
21
|
create_client,
|
|
14
22
|
handle_request,
|
|
15
23
|
options,
|
|
16
24
|
debug,
|
|
17
|
-
confirm_action,
|
|
18
25
|
set_value_from_config,
|
|
19
|
-
MutuallyExclusiveOption,
|
|
20
26
|
GLOBAL_OPTIONS,
|
|
21
27
|
OUTPUT_FORMAT_OPTION,
|
|
22
|
-
DEFAULT_CONFIGURATOR_ID,
|
|
23
|
-
REGIONS_WITH_CONFIGURATOR,
|
|
24
|
-
REGIONS_WITH_IPV6,
|
|
25
28
|
)
|
|
26
29
|
from .ssh_key import (
|
|
27
30
|
_ssh_key_list,
|
|
@@ -30,6 +33,7 @@ from .ssh_key import (
|
|
|
30
33
|
)
|
|
31
34
|
from .image import _image_list
|
|
32
35
|
from .project import (
|
|
36
|
+
get_default_project_id,
|
|
33
37
|
_project_list,
|
|
34
38
|
_project_resource_list_servers,
|
|
35
39
|
_project_resource_move,
|
|
@@ -459,17 +463,6 @@ def get_os_id_by_name(os_images: list, os_name: str) -> int:
|
|
|
459
463
|
return os_id
|
|
460
464
|
|
|
461
465
|
|
|
462
|
-
def get_project_id_by_server_id(client, projects: list, server_id: int) -> int:
|
|
463
|
-
"""Return project_id by server_id."""
|
|
464
|
-
for project in projects:
|
|
465
|
-
for server in _project_resource_list_servers(
|
|
466
|
-
client, project["id"]
|
|
467
|
-
).json()["servers"]:
|
|
468
|
-
if server["id"] == server_id:
|
|
469
|
-
return project["id"]
|
|
470
|
-
return None
|
|
471
|
-
|
|
472
|
-
|
|
473
466
|
def size_to_mb(size: str) -> int:
|
|
474
467
|
"""Transform string like '5G' into integer in megabytes.
|
|
475
468
|
Case insensitive. For example::
|
|
@@ -733,6 +726,7 @@ def server_create(
|
|
|
733
726
|
"""Create Cloud Server."""
|
|
734
727
|
# pylint: disable=too-many-locals
|
|
735
728
|
# pylint: disable=too-many-branches
|
|
729
|
+
# pylint: disable=too-many-statements
|
|
736
730
|
|
|
737
731
|
client = create_client(config, profile)
|
|
738
732
|
|
|
@@ -816,14 +810,14 @@ def server_create(
|
|
|
816
810
|
|
|
817
811
|
# Add created server to project if set
|
|
818
812
|
if project_id:
|
|
813
|
+
src_project = get_default_project_id(client)
|
|
814
|
+
# Make useless request to avoid API bug (409 resource_not_found)
|
|
815
|
+
_r = _project_resource_list_servers(client, src_project)
|
|
819
816
|
new_server_id = response.json()["server"]["id"]
|
|
820
817
|
debug(f"Add server '{new_server_id}' to project '{project_id}'")
|
|
821
|
-
old_project_id = get_project_id_by_server_id(
|
|
822
|
-
client, projects, new_server_id
|
|
823
|
-
)
|
|
824
818
|
project_resp = _project_resource_move(
|
|
825
819
|
client,
|
|
826
|
-
from_project=
|
|
820
|
+
from_project=src_project,
|
|
827
821
|
to_project=project_id,
|
|
828
822
|
resource_id=new_server_id,
|
|
829
823
|
resource_type="server",
|
|
@@ -842,7 +836,9 @@ def server_create(
|
|
|
842
836
|
# ------------------------------------------------------------- #
|
|
843
837
|
|
|
844
838
|
|
|
845
|
-
@server.command(
|
|
839
|
+
@server.command(
|
|
840
|
+
"set-property", aliases=["set"], help="Update Cloud Server properties."
|
|
841
|
+
)
|
|
846
842
|
@options(GLOBAL_OPTIONS)
|
|
847
843
|
@options(OUTPUT_FORMAT_OPTION)
|
|
848
844
|
@click.option("--name", help="Cloud server display name.")
|
|
@@ -1057,7 +1053,7 @@ def server_resize(
|
|
|
1057
1053
|
|
|
1058
1054
|
# Prompt if no option --yes passed
|
|
1059
1055
|
if not confirmed:
|
|
1060
|
-
if not
|
|
1056
|
+
if not click.confirm("Server will restart. Continue?", default=False):
|
|
1061
1057
|
sys.exit("Aborted!")
|
|
1062
1058
|
|
|
1063
1059
|
# Make request
|
|
@@ -1196,6 +1192,14 @@ def server_remove(config, profile, verbose, server_ids):
|
|
|
1196
1192
|
|
|
1197
1193
|
for server_id in server_ids:
|
|
1198
1194
|
response = _server_remove(client, server_id)
|
|
1195
|
+
|
|
1196
|
+
if response.status_code == 200:
|
|
1197
|
+
del_hash = response.json()["server_delete"]["hash"]
|
|
1198
|
+
del_code = click.prompt("Please enter confirmation code", type=int)
|
|
1199
|
+
response = _server_remove(
|
|
1200
|
+
client, server_id, delete_hash=del_hash, code=del_code
|
|
1201
|
+
)
|
|
1202
|
+
|
|
1199
1203
|
if response.status_code == 204:
|
|
1200
1204
|
click.echo(server_id)
|
|
1201
1205
|
else:
|
|
@@ -1316,10 +1320,9 @@ def print_presets(response: object, filters: str):
|
|
|
1316
1320
|
"FREQ",
|
|
1317
1321
|
"RAM",
|
|
1318
1322
|
"DISK",
|
|
1319
|
-
"
|
|
1320
|
-
"
|
|
1321
|
-
"
|
|
1322
|
-
"LOCAL NETWORK",
|
|
1323
|
+
"TYPE",
|
|
1324
|
+
"BANDW",
|
|
1325
|
+
"LAN",
|
|
1323
1326
|
]
|
|
1324
1327
|
)
|
|
1325
1328
|
for preset in presets:
|
|
@@ -1334,14 +1337,15 @@ def print_presets(response: object, filters: str):
|
|
|
1334
1337
|
str(round(preset["disk"] / 1024)) + "G",
|
|
1335
1338
|
preset["disk_type"],
|
|
1336
1339
|
preset["bandwidth"],
|
|
1337
|
-
preset["description_short"],
|
|
1338
1340
|
preset["is_allowed_local_network"],
|
|
1339
1341
|
]
|
|
1340
1342
|
)
|
|
1341
1343
|
table.print()
|
|
1342
1344
|
|
|
1343
1345
|
|
|
1344
|
-
@server.command(
|
|
1346
|
+
@server.command(
|
|
1347
|
+
"list-presets", aliases=["lp"], help="List configuration presets."
|
|
1348
|
+
)
|
|
1345
1349
|
@options(GLOBAL_OPTIONS)
|
|
1346
1350
|
@options(OUTPUT_FORMAT_OPTION)
|
|
1347
1351
|
@click.option("--region", "-r", help="Use region (location).")
|
|
@@ -1399,7 +1403,9 @@ def print_os_images(response: object, filters: str):
|
|
|
1399
1403
|
|
|
1400
1404
|
|
|
1401
1405
|
@server.command(
|
|
1402
|
-
"list-os-images",
|
|
1406
|
+
"list-os-images",
|
|
1407
|
+
aliases=["li"],
|
|
1408
|
+
help="List prebuilt operating system images.",
|
|
1403
1409
|
)
|
|
1404
1410
|
@options(GLOBAL_OPTIONS)
|
|
1405
1411
|
@options(OUTPUT_FORMAT_OPTION)
|
|
@@ -1456,7 +1462,9 @@ def print_logs(response: object):
|
|
|
1456
1462
|
)
|
|
1457
1463
|
|
|
1458
1464
|
|
|
1459
|
-
@server.command(
|
|
1465
|
+
@server.command(
|
|
1466
|
+
"history", aliases=["logs"], help="View Cloud Server events log."
|
|
1467
|
+
)
|
|
1460
1468
|
@options(GLOBAL_OPTIONS)
|
|
1461
1469
|
@options(OUTPUT_FORMAT_OPTION)
|
|
1462
1470
|
@click.option(
|
|
@@ -2089,11 +2097,8 @@ def print_backups(response: object):
|
|
|
2089
2097
|
[
|
|
2090
2098
|
"ID",
|
|
2091
2099
|
"DISK",
|
|
2092
|
-
"STATUS",
|
|
2093
2100
|
"CREATED",
|
|
2094
|
-
"
|
|
2095
|
-
"TYPE",
|
|
2096
|
-
"COMMENT",
|
|
2101
|
+
"STATUS",
|
|
2097
2102
|
]
|
|
2098
2103
|
)
|
|
2099
2104
|
for backup in backups:
|
|
@@ -2101,11 +2106,8 @@ def print_backups(response: object):
|
|
|
2101
2106
|
[
|
|
2102
2107
|
backup["id"],
|
|
2103
2108
|
backup["name"],
|
|
2104
|
-
backup["status"],
|
|
2105
2109
|
backup["created_at"],
|
|
2106
|
-
|
|
2107
|
-
backup["type"],
|
|
2108
|
-
backup["comment"],
|
|
2110
|
+
backup["status"],
|
|
2109
2111
|
]
|
|
2110
2112
|
)
|
|
2111
2113
|
table.print()
|
|
@@ -2134,22 +2136,16 @@ def print_backup(response: object):
|
|
|
2134
2136
|
[
|
|
2135
2137
|
"ID",
|
|
2136
2138
|
"DISK",
|
|
2137
|
-
"STATUS",
|
|
2138
2139
|
"CREATED",
|
|
2139
|
-
"
|
|
2140
|
-
"TYPE",
|
|
2141
|
-
"COMMENT",
|
|
2140
|
+
"STATUS",
|
|
2142
2141
|
]
|
|
2143
2142
|
)
|
|
2144
2143
|
table.row(
|
|
2145
2144
|
[
|
|
2146
2145
|
backup["id"],
|
|
2147
2146
|
backup["name"],
|
|
2148
|
-
backup["status"],
|
|
2149
2147
|
backup["created_at"],
|
|
2150
|
-
|
|
2151
|
-
backup["type"],
|
|
2152
|
-
backup["comment"],
|
|
2148
|
+
backup["status"],
|
|
2153
2149
|
]
|
|
2154
2150
|
)
|
|
2155
2151
|
table.print()
|
|
@@ -2199,7 +2195,9 @@ def server_backup_create(
|
|
|
2199
2195
|
# ------------------------------------------------------------- #
|
|
2200
2196
|
|
|
2201
2197
|
|
|
2202
|
-
@backup.command(
|
|
2198
|
+
@backup.command(
|
|
2199
|
+
"set-property", aliases=["set"], help="Change backup properties."
|
|
2200
|
+
)
|
|
2203
2201
|
@options(GLOBAL_OPTIONS)
|
|
2204
2202
|
@options(OUTPUT_FORMAT_OPTION)
|
|
2205
2203
|
@click.option("--comment", type=str, default=None, help="Comment.")
|
|
@@ -2305,3 +2303,47 @@ def server_backup_unmount(config, profile, verbose, disk_id, backup_id):
|
|
|
2305
2303
|
click.echo(server_id)
|
|
2306
2304
|
else:
|
|
2307
2305
|
fmt.printer(response)
|
|
2306
|
+
|
|
2307
|
+
|
|
2308
|
+
# ------------------------------------------------------------- #
|
|
2309
|
+
# $ twc server dash #
|
|
2310
|
+
# ------------------------------------------------------------- #
|
|
2311
|
+
|
|
2312
|
+
|
|
2313
|
+
@server.command("dash", help="Open Cloud Server dashboard in web browser.")
|
|
2314
|
+
@options(GLOBAL_OPTIONS[:2])
|
|
2315
|
+
@click.option(
|
|
2316
|
+
"--tab/--win",
|
|
2317
|
+
default=True,
|
|
2318
|
+
show_default=True,
|
|
2319
|
+
help="Open in new tab or new window.",
|
|
2320
|
+
)
|
|
2321
|
+
@click.argument("server_id", type=int, required=True)
|
|
2322
|
+
def server_dash(tab, server_id):
|
|
2323
|
+
url = f"{TWC_CP_URL}/servers/{server_id}"
|
|
2324
|
+
if tab:
|
|
2325
|
+
webbrowser.open_new_tab(url)
|
|
2326
|
+
else:
|
|
2327
|
+
webbrowser.open_new(url)
|
|
2328
|
+
|
|
2329
|
+
|
|
2330
|
+
# ------------------------------------------------------------- #
|
|
2331
|
+
# $ twc server vnc #
|
|
2332
|
+
# ------------------------------------------------------------- #
|
|
2333
|
+
|
|
2334
|
+
|
|
2335
|
+
@server.command("vnc", help="Open Cloud Server web VNC console in browser.")
|
|
2336
|
+
@options(GLOBAL_OPTIONS[:2])
|
|
2337
|
+
@click.option(
|
|
2338
|
+
"--tab/--win",
|
|
2339
|
+
default=True,
|
|
2340
|
+
show_default=True,
|
|
2341
|
+
help="Open in new tab or new window.",
|
|
2342
|
+
)
|
|
2343
|
+
@click.argument("server_id", type=int, required=True)
|
|
2344
|
+
def server_vnc(tab, server_id):
|
|
2345
|
+
url = f"{TWC_CP_URL}/servers/{server_id}/console"
|
|
2346
|
+
if tab:
|
|
2347
|
+
webbrowser.open_new_tab(url)
|
|
2348
|
+
else:
|
|
2349
|
+
webbrowser.open_new(url)
|