Merge branch 'wip' into 'master'

See merge request ucloud/ucloud-cli!2
This commit is contained in:
Ahmed Bilal 2019-11-11 19:49:35 +01:00
commit d1dd2839b7
9 changed files with 193 additions and 90 deletions

View File

@ -12,4 +12,4 @@ pyotp = "*"
click = "*"
[requires]
python_version = "3.7"
python_version = "3.5"

16
Pipfile.lock generated
View File

@ -1,11 +1,11 @@
{
"_meta": {
"hash": {
"sha256": "1f6e0448a1e04906885393b4ff57423363593680a7b6f73a5ed1f514496bb1f3"
"sha256": "ad97ea0bec676c536266766c718bd590b17e0e28d47728ab68cf21d09fbb07d4"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.7"
"python_version": "3.5"
},
"sources": [
{
@ -18,10 +18,10 @@
"default": {
"certifi": {
"hashes": [
"sha256:046832c04d4e752f37383b628bc601a7ea7211496b4638f6514d0e5b9acc4939",
"sha256:945e3ba63a0b9f577b1395204e13c3a231f9bc0223888be653286534e5873695"
"sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50",
"sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef"
],
"version": "==2019.6.16"
"version": "==2019.9.11"
},
"chardet": {
"hashes": [
@ -47,11 +47,11 @@
},
"pyotp": {
"hashes": [
"sha256:1e3dc3d16919c4efac528d1dbecc17de1a97c4ecfdacb89d7726ed2c6645adff",
"sha256:be0ffeabddaa5ee53e7204e7740da842d070cf69168247a3d0c08541b84de602"
"sha256:c88f37fd47541a580b744b42136f387cdad481b560ef410c0d85c957eb2a2bc0",
"sha256:fc537e8acd985c5cbf51e11b7d53c42276fee017a73aec7c07380695671ca1a1"
],
"index": "pypi",
"version": "==2.2.7"
"version": "==2.3.0"
},
"python-decouple": {
"hashes": [

View File

@ -1,21 +1,20 @@
import click
import json
from dataclasses import dataclass
from pyotp import TOTP
@dataclass
class OTPCredentials:
name: str
realm: str
seed: str
def __init__(self, name, realm, seed):
self.name = name # type: str
self.realm = realm # type: str
self.seed = seed # type: str
def get_json(self):
r = {"name": self.name, "realm": self.realm, "token": TOTP(self.seed).now()}
return r
return {"name": self.name, "realm": self.realm, "token": TOTP(self.seed).now()}
def load_dump_pretty(content):
if isinstance(content, bytes):
content = content.decode("utf-8")
parsed = json.loads(content)
return json.dumps(parsed, indent=4, sort_keys=True)
return json.dumps(parsed, indent=4, sort_keys=True)

View File

@ -1,9 +1,10 @@
import click
import json
import requests
from commands.helper import OTPCredentials, load_dump_pretty
from decouple import config
from .helper import OTPCredentials, load_dump_pretty
import click
import requests
@click.group()
@ -11,25 +12,30 @@ def host():
pass
@host.command("add")
@host.command("create")
@click.option("--name", envvar="OTP_NAME", required=True)
@click.option("--realm", envvar="OTP_REALM", required=True)
@click.option("--seed", envvar="OTP_SEED", required=True)
@click.option("--specs", required=True)
@click.option("--hostname", required=True)
def add_host(name, realm, seed, specs, hostname):
with open(specs, "r") as specs_f:
specs = json.loads(specs_f.read())
data = {
**OTPCredentials(name, realm, seed).get_json(),
"specs": specs,
"hostname": hostname,
}
r = requests.post(f"{config('UCLOUD_API_SERVER')}/host/create", json=data)
print(load_dump_pretty(r.content))
@click.option("--cpu", required=True, type=int)
@click.option("--ram", required=True)
@click.option("--os-ssd", required=True)
@click.option("--hdd", default=list(), multiple=True)
def create(name, realm, seed, hostname, cpu, ram, os_ssd, hdd):
data = {
**OTPCredentials(name, realm, seed).get_json(),
"hostname": hostname,
"specs": {
'cpu': cpu,
'ram': ram,
'os-ssd': os_ssd,
'hdd': hdd
},
}
r = requests.post("{}/host/create".format(config('UCLOUD_API_SERVER')), json=data)
print(load_dump_pretty(r.content))
@host.command("list")
def list_host():
r = requests.get(f"{config('UCLOUD_API_SERVER')}/host/list")
print(load_dump_pretty(r.content))
r = requests.get("{}/host/list".format(config('UCLOUD_API_SERVER')))
print(load_dump_pretty(r.content))

View File

@ -1,10 +1,8 @@
import click
import json
import requests
from commands.helper import load_dump_pretty
from decouple import config
from .helper import OTPCredentials, load_dump_pretty
import click
import requests
@click.group()
def image():
@ -16,15 +14,15 @@ def image():
@click.option("--private", is_flag=True)
def _list(public, private):
if public:
r = requests.get(f"{config('UCLOUD_API_SERVER')}/image/list-public")
r = requests.get("{}/image/list-public".format(config('UCLOUD_API_SERVER')))
print(load_dump_pretty(r.content))
@image.command("create-from-file")
@click.option("--name", required=True)
@click.option("--uuid", required=True)
@click.option("--image_store_name", required=True)
@click.option("--image-store-name", required=True)
def create_from_file(name, uuid, image_store_name):
data = {"name": name, "uuid": uuid, "image_store": image_store_name}
r = requests.post(f"{config('UCLOUD_API_SERVER')}/image/create", json=data)
r = requests.post("{}/image/create".format(config('UCLOUD_API_SERVER')), json=data)
print(load_dump_pretty(r.content))

25
commands/network.py Normal file
View File

@ -0,0 +1,25 @@
from commands.helper import load_dump_pretty, OTPCredentials
from decouple import config
import click
import requests
@click.group()
def network():
pass
@network.command("create")
@click.option("--name", envvar="OTP_NAME", required=True)
@click.option("--realm", envvar="OTP_REALM", required=True)
@click.option("--seed", envvar="OTP_SEED", required=True)
@click.option("--network-name", required=True)
@click.option("--network-type", required=True)
def create(name, realm, seed, network_name, network_type):
data = {
**OTPCredentials(name, realm, seed).get_json(),
"network_name": network_name,
"type": network_type
}
r = requests.post("{}/network/create".format(config('UCLOUD_API_SERVER')), json=data)
print(load_dump_pretty(r.content))

View File

@ -1,9 +1,8 @@
import click
import json
import requests
from commands.helper import OTPCredentials, load_dump_pretty
from decouple import config
from .helper import OTPCredentials, load_dump_pretty
import click
import requests
@click.group()
@ -17,7 +16,7 @@ def user():
@click.option("--seed", envvar="OTP_SEED", required=True)
def list_files(name, realm, seed):
data = OTPCredentials(name, realm, seed).get_json()
r = requests.get(f"{config('UCLOUD_API_SERVER')}/user/files", json=data)
r = requests.get("{}/user/files".format(config('UCLOUD_API_SERVER')), json=data)
print(load_dump_pretty(r.content))
@ -27,5 +26,61 @@ def list_files(name, realm, seed):
@click.option("--seed", envvar="OTP_SEED", required=True)
def list_vms(name, realm, seed):
data = OTPCredentials(name, realm, seed).get_json()
r = requests.get(f"{config('UCLOUD_API_SERVER')}/user/vms", json=data)
r = requests.get("{}/user/vms".format(config('UCLOUD_API_SERVER')), json=data)
print(load_dump_pretty(r.content))
@user.command("network")
@click.option("--name", envvar="OTP_NAME", required=True)
@click.option("--realm", envvar="OTP_REALM", required=True)
@click.option("--seed", envvar="OTP_SEED", required=True)
def list_files(name, realm, seed):
data = OTPCredentials(name, realm, seed).get_json()
r = requests.get("{}/user/networks".format(config('UCLOUD_API_SERVER')), json=data)
print(load_dump_pretty(r.content))
@user.command("add-ssh")
@click.option("--name", envvar="OTP_NAME", required=True)
@click.option("--realm", envvar="OTP_REALM", required=True)
@click.option("--seed", envvar="OTP_SEED", required=True)
@click.option("--key-name", required=True)
@click.option("--key", required=True)
def add_ssh(name, realm, seed, key_name, key):
otp = OTPCredentials(name, realm, seed)
data = {
**otp.get_json(),
"key_name": key_name,
"key": key
}
r = requests.post("{}/user/add-ssh".format(config('UCLOUD_API_SERVER')), json=data)
print(load_dump_pretty(r.content))
@user.command("remove-ssh")
@click.option("--name", envvar="OTP_NAME", required=True)
@click.option("--realm", envvar="OTP_REALM", required=True)
@click.option("--seed", envvar="OTP_SEED", required=True)
@click.option("--key-name", required=True)
def remove_ssh(name, realm, seed, key_name):
otp = OTPCredentials(name, realm, seed)
data = {
**otp.get_json(),
"key_name": key_name,
}
r = requests.get("{}/user/remove-ssh".format(config('UCLOUD_API_SERVER')), json=data)
print(load_dump_pretty(r.content))
@user.command("get-ssh")
@click.option("--name", envvar="OTP_NAME", required=True)
@click.option("--realm", envvar="OTP_REALM", required=True)
@click.option("--seed", envvar="OTP_SEED", required=True)
@click.option("--key-name", default="")
def add_ssh(name, realm, seed, key_name):
otp = OTPCredentials(name, realm, seed)
data = {
**otp.get_json(),
"key_name": key_name,
}
r = requests.get("{}/user/get-ssh".format(config('UCLOUD_API_SERVER')), json=data)
print(load_dump_pretty(r.content))

View File

@ -1,14 +1,15 @@
import click
import json
from commands.helper import OTPCredentials, load_dump_pretty
from decouple import config
import click
import requests
from decouple import config
from .helper import OTPCredentials, load_dump_pretty
def vm_command(command, otp, uuid):
data = {**otp.get_json(), "uuid": uuid, "action": command}
r = requests.post(f"{config('UCLOUD_API_SERVER')}/vm/action", json=data)
def vm_command(command, otp, vm_name, **kwargs):
data = {**otp.get_json(), "vm_name": vm_name, "action": command, **kwargs}
r = requests.post("{}/vm/action".format(config('UCLOUD_API_SERVER')), json=data)
return r
@ -21,27 +22,38 @@ def vm():
@click.option("--name", envvar="OTP_NAME", required=True)
@click.option("--realm", envvar="OTP_REALM", required=True)
@click.option("--seed", envvar="OTP_SEED", required=True)
@click.option("--specs", required=True)
@click.option("--image_uuid", required=True)
def create(name, realm, seed, specs, image_uuid):
with open(specs, "r") as specs_f:
specs = json.loads(specs_f.read())
data = {
**OTPCredentials(name, realm, seed).get_json(),
"specs": specs,
"image_uuid": image_uuid,
}
r = requests.post(f"{config('UCLOUD_API_SERVER')}/vm/create", json=data)
print(load_dump_pretty(r.content))
@click.option("--vm-name", required=True)
@click.option("--cpu", required=True, type=int)
@click.option("--ram", required=True)
@click.option("--os-ssd", required=True)
@click.option("--hdd", default=list(), multiple=True)
@click.option("--image", required=True)
@click.option("--network", default=list(), multiple=True)
def create(name, realm, seed, vm_name, cpu, ram, os_ssd, hdd, image, network):
data = {
**OTPCredentials(name, realm, seed).get_json(),
"vm_name": vm_name,
"specs": {
'cpu': cpu,
'ram': ram,
'os-ssd': os_ssd,
'hdd': hdd
},
"network": network,
"image": image,
}
r = requests.post("{}/vm/create".format(config('UCLOUD_API_SERVER')), json=data)
print(load_dump_pretty(r.content))
@vm.command("start")
@click.option("--name", envvar="OTP_NAME", required=True)
@click.option("--realm", envvar="OTP_REALM", required=True)
@click.option("--seed", envvar="OTP_SEED", required=True)
@click.option("--uuid", required=True)
def start(name, realm, seed, uuid):
r = vm_command("start", OTPCredentials(name, realm, seed), uuid)
@click.option("--vm-name", required=True)
@click.option("--in_support_of")
def start(name, realm, seed, vm_name, in_support_of):
r = vm_command("start", OTPCredentials(name, realm, seed), vm_name, in_support_of=in_support_of)
print(load_dump_pretty(r.content))
@ -49,9 +61,10 @@ def start(name, realm, seed, uuid):
@click.option("--name", envvar="OTP_NAME", required=True)
@click.option("--realm", envvar="OTP_REALM", required=True)
@click.option("--seed", envvar="OTP_SEED", required=True)
@click.option("--uuid", required=True)
def stop(name, realm, seed, uuid):
r = vm_command("stop", OTPCredentials(name, realm, seed), uuid)
@click.option("--vm-name", required=True)
@click.option("--in_support_of")
def stop(name, realm, seed, vm_name, in_support_of):
r = vm_command("stop", OTPCredentials(name, realm, seed), vm_name, in_support_of=in_support_of)
print(load_dump_pretty(r.content))
@ -59,9 +72,10 @@ def stop(name, realm, seed, uuid):
@click.option("--name", envvar="OTP_NAME", required=True)
@click.option("--realm", envvar="OTP_REALM", required=True)
@click.option("--seed", envvar="OTP_SEED", required=True)
@click.option("--uuid", required=True)
def delete(name, realm, seed, uuid):
r = vm_command("delete", OTPCredentials(name, realm, seed), uuid)
@click.option("--vm-name", required=True)
@click.option("--in_support_of")
def delete(name, realm, seed, vm_name, in_support_of):
r = vm_command("delete", OTPCredentials(name, realm, seed), vm_name, in_support_of=in_support_of)
print(load_dump_pretty(r.content))
@ -69,24 +83,29 @@ def delete(name, realm, seed, uuid):
@click.option("--name", envvar="OTP_NAME", required=True)
@click.option("--realm", envvar="OTP_REALM", required=True)
@click.option("--seed", envvar="OTP_SEED", required=True)
@click.option("--uuid", required=True)
def status(name, realm, seed, uuid):
data = {"name": name, "realm": realm, "seed": seed, "uuid": uuid}
r = requests.get(f"{config('UCLOUD_API_SERVER')}/vm/status", json=data)
@click.option("--vm-name", required=True)
@click.option("--in_support_of")
def status(name, realm, seed, vm_name, in_support_of):
otp = OTPCredentials(name, realm, seed)
data = {**otp.get_json(), "vm_name": vm_name, "in_support_of": in_support_of}
r = requests.get("{}/vm/status".format(config('UCLOUD_API_SERVER')), json=data)
print(load_dump_pretty(r.content))
@vm.command("migrate")
@click.option("--name", envvar="OTP_NAME", required=True)
@click.option("--realm", envvar="OTP_REALM", required=True)
@click.option("--seed", envvar="OTP_SEED", required=True)
@click.option("--uuid", required=True)
@click.option("--vm-name", required=True)
@click.option("--destination", required=True)
def vm_migration(name, realm, seed, uuid, destination):
@click.option("--in_support_of")
def vm_migration(name, realm, seed, vm_name, destination, in_support_of):
otp = OTPCredentials(name, realm, seed)
data = {
**otp.get_json(),
"uuid": uuid,
"destination": destination
"vm_name": vm_name,
"destination": destination,
"in_support_of": in_support_of,
}
r = requests.post(f"{config('UCLOUD_API_SERVER')}/vm/migrate", json=data)
print(load_dump_pretty(r.content))
r = requests.post("{}/vm/migrate".format(config('UCLOUD_API_SERVER')), json=data)
print(load_dump_pretty(r.content))

View File

@ -4,7 +4,7 @@ from commands.vm import vm
from commands.user import user
from commands.host import host
from commands.image import image
from commands.network import network
@click.group()
def entry_point():
@ -15,6 +15,7 @@ entry_point.add_command(vm)
entry_point.add_command(user)
entry_point.add_command(image)
entry_point.add_command(host)
entry_point.add_command(network)
if __name__ == "__main__":
entry_point()