-
Notifications
You must be signed in to change notification settings - Fork 1
/
one-vm-list.py
executable file
·159 lines (133 loc) · 4.61 KB
/
one-vm-list.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/env python3
import argparse
import datetime
import json
import os
import pyone
import sys
import subprocess
import time
ONE_DIR = os.path.expanduser('~/.one')
ONE_AUTH = 'one_auth'
ONE_ENDPOINT = 'endpoint'
ONE_CACHE = 'cache'
CACHE_TIME = 30 # in seconds
def create_one_dir():
os.makedirs(ONE_DIR, exist_ok=True)
def get_one_auth_data():
"""
Return (username, password, endpoint) tuple.
"""
try:
with open(ONE_DIR + '/' + ONE_AUTH) as f:
one_user, one_password = f.readline().strip().split(":", 1)
except:
try:
one_user = os.environ['ONE_USER']
one_password = os.environ['ONE_PASSWORD']
except KeyError:
sys.exit('You must specify OpenNebula credentials in '
'~/.one/one_auth file or in environment variables')
try:
with open(ONE_DIR + '/' + ONE_ENDPOINT) as f:
one_endpoint = f.readline().strip()
except:
try:
one_endpoint = os.environ['ONE_ENDPOINT']
except KeyError:
sys.exit('You must specify OpenNebula XML-RPC endpoint in '
'~/.one/endpoint file or in environment variable')
return one_user, one_password, one_endpoint
def get_cache():
"""
Return cache vm data or None.
"""
path_cache = ONE_DIR + '/' + ONE_CACHE
if os.path.exists(path_cache):
with open(path_cache) as f:
cache_json = json.load(f)
# check last update time
if cache_json.get('timestamp'):
last_update = datetime.datetime.fromtimestamp(
cache_json['timestamp'])
delta = datetime.timedelta(seconds=CACHE_TIME)
now = datetime.datetime.now()
if (now - last_update) < delta:
return cache_json['vms']
def set_cache(one_data: dict) -> None:
data = {
'timestamp': time.time(),
'vms': one_data
}
with open(ONE_DIR + '/' + ONE_CACHE, 'w') as f:
json.dump(data, f)
def get_one_info(one_user, one_password, one_endpoint) -> dict:
"""
Return data of virtual machines from OpenNebula.
"""
one = pyone.OneServer(
one_endpoint, session="{}:{}".format(one_user, one_password))
vm_pool = one.vmpool.info(
-3, # only own vm
-1, # When the next parameter is >= -1 this is the Range start ID.
# Can be -1. For smaller values this is the offset used for
# pagination.
-1, # For values >= -1 this is the Range end ID. Can be -1 to get
# until the last ID. For values < -1 this is the page size used
# for pagination.
3 # vm stat - active
)
vms = dict()
for vm in vm_pool.get_VM():
vms[vm.get_NAME()] = vm.get_TEMPLATE()["NIC"]["IP"]
return vms
def run_command(one_vms) -> None:
parser = argparse.ArgumentParser()
parser.add_argument(
'command', nargs='*',
help='''
listvms - show list of VMs,
ssh vm - connect to vm,
scp vm file [/path/to/file/on/vm] - scp file to vm if path/to not set used same,
rsync vm /path/on/vm - rsync current folder to vm,
ping vm
''') # noqa
args = parser.parse_args()
if args.command[0] == 'listvms':
for k, v in one_vms.items():
print(k, v)
elif args.command[0] == 'ssh':
subprocess.call(['ssh', 'root@{}'.format(one_vms[args.command[1]])])
elif args.command[0] == 'ping':
try:
subprocess.call(['ping', one_vms[args.command[1]]])
except KeyboardInterrupt:
pass
elif args.command[0] == 'scp':
vm_name = args.command[1]
path_to_files = args.command[2:-1]
if len(args.command) < 4:
print("""Need to use at least 3 arguments, for example:
onescp vm-name myfile /home/user
Last argument - destination folder on remote.""")
else:
path_on_remote = args.command[-1]
print("Sent files to {}:{}".format(vm_name, path_on_remote))
subprocess.call([
'scp', *path_to_files,
'root@{}:{}'.format(one_vms[vm_name], path_on_remote)])
elif args.command[0] == 'rsync':
subprocess.call([
'rsync', '-av', '--chown=root:root', '.',
'root@{}:{}'.format(one_vms[args.command[1]], args.command[2])
])
def main():
create_one_dir()
user, password, endpoint = get_one_auth_data()
vms = get_cache()
if vms is None:
vms = get_one_info(user, password, endpoint)
set_cache(vms)
run_command(vms)
if __name__ == '__main__':
main()