Compare commits
11 Commits
9435a46fbd
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| aea65450b9 | |||
| 975dab4bc5 | |||
| 1436a8d777 | |||
| 9cb19cf4b5 | |||
| efb2fc09ee | |||
| 79dbcbd943 | |||
| b2872e92d9 | |||
| 288ccd7357 | |||
| 94953ccf16 | |||
| 2446a74b76 | |||
| e84f13161a |
199
twvdscli.py
199
twvdscli.py
@@ -16,19 +16,26 @@ from time import sleep
|
|||||||
|
|
||||||
|
|
||||||
app = typer.Typer()
|
app = typer.Typer()
|
||||||
|
# twvdscli dbs
|
||||||
dbs_app = typer.Typer()
|
dbs_app = typer.Typer()
|
||||||
app.add_typer(dbs_app, name='dbs', help='Control Managed databases')
|
app.add_typer(dbs_app, name='dbs', help='Control Managed databases')
|
||||||
|
|
||||||
|
# twvdscli vds
|
||||||
servers_app = typer.Typer()
|
servers_app = typer.Typer()
|
||||||
app.add_typer(servers_app, name='vds', help='Control VDS Servers, their snapshots and backups')
|
app.add_typer(servers_app, name='vds', help='Control VDS Servers, their snapshots and backups')
|
||||||
|
|
||||||
|
# twvdscli vds backups
|
||||||
backups_app = typer.Typer()
|
backups_app = typer.Typer()
|
||||||
servers_app.add_typer(backups_app, name='backup', help='Create/Delete backup')
|
servers_app.add_typer(backups_app, name='backup', help='Create/Delete backup')
|
||||||
|
|
||||||
|
# twvdscli vds snap
|
||||||
snapshot_app = typer.Typer()
|
snapshot_app = typer.Typer()
|
||||||
servers_app.add_typer(snapshot_app, name='snap', help='Create/Rollback/Delete snapshot')
|
servers_app.add_typer(snapshot_app, name='snap', help='Create/Rollback/Delete snapshot')
|
||||||
|
|
||||||
|
# twvdscli vds info
|
||||||
|
vds_info_app = typer.Typer()
|
||||||
|
servers_app.add_typer(vds_info_app, name='info', help='Get info about plans and os\'es')
|
||||||
|
|
||||||
|
|
||||||
class Dbaas:
|
class Dbaas:
|
||||||
"""
|
"""
|
||||||
@@ -429,12 +436,15 @@ def dbs_create(passwd: str = typer.Option(..., help="DB password"),
|
|||||||
|
|
||||||
|
|
||||||
@dbs_app.command("list")
|
@dbs_app.command("list")
|
||||||
def dbs_list():
|
def dbs_list(raw: bool = typer.Option(False, help="Get result as raw json")):
|
||||||
"""
|
"""
|
||||||
Show list of DBs:
|
Show list of DBs:
|
||||||
ID, State, Name, IP, local IP, Password, Type
|
ID, State, Name, IP, local IP, Password, Type
|
||||||
"""
|
"""
|
||||||
list_of_dbaas = Dbaas.list()
|
list_of_dbaas = Dbaas.list()
|
||||||
|
if raw:
|
||||||
|
print(list_of_dbaas)
|
||||||
|
return
|
||||||
x = PrettyTable()
|
x = PrettyTable()
|
||||||
x.field_names = ['id', 'state', 'name', 'ip', 'local_ip', 'password', 'type']
|
x.field_names = ['id', 'state', 'name', 'ip', 'local_ip', 'password', 'type']
|
||||||
if list_of_dbaas is None:
|
if list_of_dbaas is None:
|
||||||
@@ -492,6 +502,140 @@ def dbs_connect(db_id: Optional[int] = typer.Argument(None)):
|
|||||||
os.system(cmd_psql.format(ip=db_ip, login=db_user))
|
os.system(cmd_psql.format(ip=db_ip, login=db_user))
|
||||||
|
|
||||||
|
|
||||||
|
@vds_info_app.command("plans")
|
||||||
|
def vds_plans(raw: bool = typer.Option(False, help="Get result as raw json"),
|
||||||
|
sort_by: str = typer.Option(None, help="sort results by value/cpu/ram/disk")):
|
||||||
|
uri = "https://public-api.timeweb.com/api/v1/presets"
|
||||||
|
result = requests.get(uri, headers=reqHeader)
|
||||||
|
|
||||||
|
if not result.ok:
|
||||||
|
print('Error')
|
||||||
|
sys.exit(1)
|
||||||
|
# If raw - print raw result and exit
|
||||||
|
if raw:
|
||||||
|
print(result.text)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# else print pretty
|
||||||
|
x = PrettyTable()
|
||||||
|
x.field_names = ['id', 'cpus', 'ram', 'disk', 'value', 'name', 'description']
|
||||||
|
result = result.json()
|
||||||
|
print("Total: "+ str(result['meta']['total']))
|
||||||
|
# result = result
|
||||||
|
for i in result['presets']:
|
||||||
|
x.add_row([
|
||||||
|
i['id'],
|
||||||
|
i['cpu'],
|
||||||
|
i['ram'],
|
||||||
|
i['drive'],
|
||||||
|
i['discount_value'],
|
||||||
|
i['name'],
|
||||||
|
i['description']
|
||||||
|
])
|
||||||
|
if sort_by in ('cpus', 'ram', 'disk', 'value'):
|
||||||
|
x.sortby = sort_by
|
||||||
|
elif not sort_by is None:
|
||||||
|
print("No such sort")
|
||||||
|
print(x)
|
||||||
|
|
||||||
|
|
||||||
|
@vds_info_app.command("os")
|
||||||
|
def vds_oses(raw: bool = typer.Option(False, help="Get result as raw json")):
|
||||||
|
uri = "https://public-api.timeweb.com/api/v1/os"
|
||||||
|
result = requests.get(uri, headers=reqHeader)
|
||||||
|
|
||||||
|
if not result.ok:
|
||||||
|
print('Error')
|
||||||
|
sys.exit(1)
|
||||||
|
# If raw - print raw result and exit
|
||||||
|
if raw:
|
||||||
|
print(result.text)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# else print pretty
|
||||||
|
x = PrettyTable()
|
||||||
|
x.field_names = ['id', 'fullname', 'family', 'name', 'latin', 'available']
|
||||||
|
result = result.json()
|
||||||
|
print("Total: "+ str(result['meta']['total']))
|
||||||
|
# result = result
|
||||||
|
for i in result['os']:
|
||||||
|
x.add_row([
|
||||||
|
i['id'],
|
||||||
|
i['os_caption'],
|
||||||
|
i['os_type'],
|
||||||
|
i['os_name'],
|
||||||
|
i['os_latin'],
|
||||||
|
i['is_public']
|
||||||
|
])
|
||||||
|
print(x)
|
||||||
|
|
||||||
|
|
||||||
|
@servers_app.command("create")
|
||||||
|
def vds_create(
|
||||||
|
name: str = typer.Option(..., help="VDS Name"),
|
||||||
|
os_id: int = typer.Option(..., help="OS ID"),
|
||||||
|
preset: int = typer.Option(17, help="Preset ID"),
|
||||||
|
comment: str = typer.Option("", help="Comment")
|
||||||
|
):
|
||||||
|
# get user group
|
||||||
|
group_uri = "https://public-api.timeweb.com/api/v1/accounts/{user}/group"
|
||||||
|
# get username from saved base64
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read(os.path.join(os.getenv('HOME'), '.config', 'twvdscli.ini'))
|
||||||
|
based = config.get('api', 'key', fallback=None)
|
||||||
|
based = base64.b64decode(based)
|
||||||
|
based = str(based, 'utf-8')
|
||||||
|
user = based.split(':')[0]
|
||||||
|
|
||||||
|
group_id = requests.get(
|
||||||
|
group_uri.format(user=user), headers=reqHeader
|
||||||
|
)
|
||||||
|
# finally get group id
|
||||||
|
if group_id.ok:
|
||||||
|
group_id = group_id.json()['groups'][0]['id']
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"server": {
|
||||||
|
"configuration": {
|
||||||
|
"caption": name,
|
||||||
|
# "disk_size": 5, # dont give a fuck
|
||||||
|
# "network_bandwidth": 100, # dont give a fuck
|
||||||
|
"os": os_id, # 47 - ubuntu 18.04
|
||||||
|
# "xen_cpu": 2, # dont give a fuck
|
||||||
|
# "xen_ram": 4096, # dont give a fuck
|
||||||
|
"ddos_guard": False
|
||||||
|
},
|
||||||
|
"comment": comment,
|
||||||
|
"group_id": group_id, # https://public-api.timeweb.com/api/v1/accounts/{user}/group
|
||||||
|
"name": "string", # what is this for?
|
||||||
|
"preset_id": preset, # you can not create vds without this, but how to create flexible vds? (preset example: 20)
|
||||||
|
"install_ssh_key": "",
|
||||||
|
"server_id": None,
|
||||||
|
"local_networks": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
"https://public-api.timeweb.com/api/v1/vds",
|
||||||
|
headers=reqHeader,
|
||||||
|
json=data
|
||||||
|
)
|
||||||
|
|
||||||
|
if not response.ok:
|
||||||
|
print(typer.style("Error", fg=typer.colors.RED))
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
response = response.json()
|
||||||
|
for frame in cycle(r'-\|/'):
|
||||||
|
state = Server.get_vds(response['server']['id'])
|
||||||
|
if state:
|
||||||
|
if state['server']['status'] == 'on':
|
||||||
|
print(typer.style("\nCreated: " + response['server']['configuration']['caption'], fg=typer.colors.GREEN))
|
||||||
|
break
|
||||||
|
print('\r', frame, sep='', end='', flush=True)
|
||||||
|
sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
@servers_app.command("goto")
|
@servers_app.command("goto")
|
||||||
def vds_goto(vds_id: Optional[int] = typer.Argument(None),
|
def vds_goto(vds_id: Optional[int] = typer.Argument(None),
|
||||||
port: int = typer.Option(22, help="Specify non standart SSH port.")):
|
port: int = typer.Option(22, help="Specify non standart SSH port.")):
|
||||||
@@ -509,18 +653,27 @@ def vds_goto(vds_id: Optional[int] = typer.Argument(None),
|
|||||||
|
|
||||||
|
|
||||||
@servers_app.command("start")
|
@servers_app.command("start")
|
||||||
def vds_start(vds_id: Optional[int] = typer.Argument(None)):
|
def vds_start(vds_id: Optional[int] = typer.Argument(None), raw: bool = typer.Option(False, help="Get result as raw json")):
|
||||||
"""
|
"""
|
||||||
Start VDS
|
Start VDS
|
||||||
"""
|
"""
|
||||||
if vds_id is None:
|
if vds_id is None:
|
||||||
|
if raw:
|
||||||
|
print(
|
||||||
|
dict(
|
||||||
|
error="No VDS ID provided"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return 1
|
||||||
vds_list()
|
vds_list()
|
||||||
vds_id = input("Enter VDS ID: ")
|
vds_id = input("Enter VDS ID: ")
|
||||||
result = Server.start(vds_id)
|
result = Server.start(vds_id)
|
||||||
if result is None:
|
if result is None:
|
||||||
print(typer.style("Error", fg=typer.colors.RED))
|
print(typer.style("Error", fg=typer.colors.RED))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
if raw:
|
||||||
|
print(result)
|
||||||
|
return
|
||||||
for frame in cycle(r'-\|/'):
|
for frame in cycle(r'-\|/'):
|
||||||
state = Server.get_vds(vds_id)
|
state = Server.get_vds(vds_id)
|
||||||
if state:
|
if state:
|
||||||
@@ -532,18 +685,26 @@ def vds_start(vds_id: Optional[int] = typer.Argument(None)):
|
|||||||
|
|
||||||
|
|
||||||
@servers_app.command("stop")
|
@servers_app.command("stop")
|
||||||
def vds_stop(vds_id: Optional[int] = typer.Argument(None)):
|
def vds_stop(vds_id: Optional[int] = typer.Argument(None), raw: bool = typer.Option(False, help="Get result as raw json")):
|
||||||
"""
|
"""
|
||||||
Stop VDS
|
Stop VDS
|
||||||
"""
|
"""
|
||||||
if vds_id is None:
|
if vds_id is None:
|
||||||
|
if raw:
|
||||||
|
print(
|
||||||
|
dict(
|
||||||
|
error="No VDS ID provided"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return 1
|
||||||
vds_list()
|
vds_list()
|
||||||
vds_id = input("Enter VDS ID: ")
|
vds_id = input("Enter VDS ID: ")
|
||||||
result = Server.stop(vds_id)
|
result = Server.stop(vds_id)
|
||||||
if result is None:
|
if result is None:
|
||||||
print(typer.style("Error", fg=typer.colors.RED))
|
print(typer.style("Error", fg=typer.colors.RED))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
if raw:
|
||||||
|
print(result)
|
||||||
for frame in cycle(r'-\|/'):
|
for frame in cycle(r'-\|/'):
|
||||||
state = Server.get_vds(vds_id)
|
state = Server.get_vds(vds_id)
|
||||||
if state:
|
if state:
|
||||||
@@ -556,11 +717,18 @@ def vds_stop(vds_id: Optional[int] = typer.Argument(None)):
|
|||||||
|
|
||||||
@servers_app.command("clone")
|
@servers_app.command("clone")
|
||||||
def vds_clone(vds_id: Optional[int] = typer.Argument(None),
|
def vds_clone(vds_id: Optional[int] = typer.Argument(None),
|
||||||
raw: bool = typer.Option(False, help="Say hi formally.")):
|
raw: bool = typer.Option(False, help="Get result as raw json")):
|
||||||
"""
|
"""
|
||||||
Clone VDS
|
Clone VDS
|
||||||
"""
|
"""
|
||||||
if vds_id is None:
|
if vds_id is None:
|
||||||
|
if raw:
|
||||||
|
print(
|
||||||
|
dict(
|
||||||
|
error="No VDS ID provided"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
vds_list()
|
vds_list()
|
||||||
vds_id = input("Enter VDS ID: ")
|
vds_id = input("Enter VDS ID: ")
|
||||||
new_vds = Server.clone(vds_id)
|
new_vds = Server.clone(vds_id)
|
||||||
@@ -568,6 +736,9 @@ def vds_clone(vds_id: Optional[int] = typer.Argument(None),
|
|||||||
print(typer.style("Error", fg=typer.colors.RED))
|
print(typer.style("Error", fg=typer.colors.RED))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
|
if raw:
|
||||||
|
print(new_vds)
|
||||||
|
return
|
||||||
new_vds = new_vds['server']
|
new_vds = new_vds['server']
|
||||||
|
|
||||||
for frame in cycle(r'-\|/'):
|
for frame in cycle(r'-\|/'):
|
||||||
@@ -581,17 +752,29 @@ def vds_clone(vds_id: Optional[int] = typer.Argument(None),
|
|||||||
|
|
||||||
|
|
||||||
@servers_app.command("remove")
|
@servers_app.command("remove")
|
||||||
def vds_remove(vds_id: Optional[int] = typer.Argument(None)):
|
def vds_remove(vds_id: Optional[int] = typer.Argument(None),
|
||||||
|
raw: bool = typer.Option(False, help="Get result as raw json")):
|
||||||
"""
|
"""
|
||||||
Remove VDS
|
Remove VDS
|
||||||
"""
|
"""
|
||||||
if vds_id is None:
|
if vds_id is None:
|
||||||
|
if raw:
|
||||||
|
print(
|
||||||
|
dict(
|
||||||
|
error="No VDS ID provided"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
vds_list()
|
vds_list()
|
||||||
vds_id = input("Enter VDS ID: ")
|
vds_id = input("Enter VDS ID: ")
|
||||||
result = Server.remove(vds_id)
|
result = Server.remove(vds_id)
|
||||||
if result is None:
|
if result is None:
|
||||||
print(typer.style("Error", fg=typer.colors.RED))
|
print(typer.style("Error", fg=typer.colors.RED))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
if raw:
|
||||||
|
print(result)
|
||||||
|
sys.exit(0)
|
||||||
for frame in cycle(r'-\|/'):
|
for frame in cycle(r'-\|/'):
|
||||||
state = Server.get_vds(vds_id)
|
state = Server.get_vds(vds_id)
|
||||||
if not state.get('server'):
|
if not state.get('server'):
|
||||||
|
|||||||
Reference in New Issue
Block a user