Directly use builtin XMLRPC client as opposed to pyone library
This commit is contained in:
parent
55a6868006
commit
78470501dd
2 changed files with 71 additions and 110 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -2,5 +2,5 @@ opennebula-vm-etcd/config-and-secrets.conf
|
||||||
|
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
||||||
.idea/
|
.idea
|
||||||
.vscode/
|
.vscode
|
||||||
|
|
|
@ -1,39 +1,17 @@
|
||||||
import pyone
|
import json
|
||||||
|
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
|
from xmlrpc.client import ServerProxy as RPCClient
|
||||||
|
|
||||||
|
from xmltodict import parse
|
||||||
|
|
||||||
from config import config, etcd_client
|
from config import config, etcd_client
|
||||||
from functools import reduce
|
|
||||||
|
|
||||||
# How to get client secrets?
|
|
||||||
# 1. Login to OpenNebula
|
|
||||||
# 2. Go to Settings then Auth
|
|
||||||
# 3. Click on "Manage login tokens" button
|
|
||||||
# 4. Click on "Get a new token" button
|
|
||||||
|
|
||||||
one_client = pyone.OneServer(
|
|
||||||
uri='https://opennebula.ungleich.ch:2634/RPC2',
|
|
||||||
session=config['oca']['client_secrets']
|
|
||||||
)
|
|
||||||
|
|
||||||
host_pool = {
|
|
||||||
host.NAME: {
|
|
||||||
'name': host.NAME,
|
|
||||||
'id': host.ID,
|
|
||||||
'cluster': {
|
|
||||||
'name': host.CLUSTER,
|
|
||||||
'id': host.CLUSTER_ID
|
|
||||||
},
|
|
||||||
'vms': host.VMS.ID
|
|
||||||
}
|
|
||||||
for host in one_client.hostpool.info().HOST
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def get_hostname_of_vm(vm_id):
|
# Constants
|
||||||
for hostname, host in host_pool.items():
|
ALL_VM_STATES = -1
|
||||||
if vm_id in host['vms']:
|
START_ID = -1 # First id whatever it is
|
||||||
return host
|
END_ID = -1 # Last id whatever it is
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def put_under_list(obj):
|
def put_under_list(obj):
|
||||||
|
@ -42,65 +20,19 @@ def put_under_list(obj):
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
class Snapshot:
|
class VMState(IntEnum):
|
||||||
def __init__(self, disk_id, snapshot):
|
INIT = 0
|
||||||
self.active = bool(snapshot.ACTIVE)
|
PENDING = 1
|
||||||
self.date = snapshot.DATE
|
HOLD = 2
|
||||||
self.id = snapshot.ID
|
ACTIVE = 3
|
||||||
self.name = snapshot.NAME
|
STOPPED = 4
|
||||||
self.size = snapshot.SIZE
|
SUSPENDED = 5
|
||||||
self.disk_id = disk_id
|
DONE = 6
|
||||||
|
FAILED = 7
|
||||||
def get_data(self):
|
POWEROFF = 8
|
||||||
return {
|
UNDEPLOYED = 9
|
||||||
attr: getattr(self, attr)
|
CLONING = 10
|
||||||
for attr in dir(self)
|
CLONING_FAILURE = 11
|
||||||
if not attr.startswith('__') and not callable(getattr(self, attr))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class VM:
|
|
||||||
def __init__(self, vm):
|
|
||||||
self.name = vm.get_NAME()
|
|
||||||
self.id = vm.get_ID()
|
|
||||||
self.owner = {
|
|
||||||
'name': vm.get_UNAME(),
|
|
||||||
'id': vm.get_UID(),
|
|
||||||
}
|
|
||||||
|
|
||||||
template = vm.get_TEMPLATE()
|
|
||||||
host = get_hostname_of_vm(self.id)
|
|
||||||
|
|
||||||
self.vcpu = template.get('VCPU', None)
|
|
||||||
self.memory = template.get('MEMORY', None)
|
|
||||||
self.disks = [dict(disk) for disk in put_under_list(template.get('DISK', []))]
|
|
||||||
self.graphics = [dict(graphics) for graphics in put_under_list(template.get('GRAPHICS', []))]
|
|
||||||
self.nics = [dict(nic) for nic in put_under_list(template.get('NIC', []))]
|
|
||||||
self.status = pyone.VM_STATE(vm.get_STATE()).name.lower()
|
|
||||||
self.snapshots = []
|
|
||||||
|
|
||||||
for disk in one_client.vm.info(self.id).SNAPSHOTS:
|
|
||||||
disk_id = disk.DISK_ID
|
|
||||||
for snapshot in disk.SNAPSHOT:
|
|
||||||
self.snapshots.append(Snapshot(disk_id, snapshot).get_data())
|
|
||||||
|
|
||||||
if host:
|
|
||||||
self.host = {
|
|
||||||
'name': host['name'],
|
|
||||||
'id': host['id']
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
self.host = host
|
|
||||||
|
|
||||||
def get_data(self):
|
|
||||||
return {
|
|
||||||
attr: getattr(self, attr)
|
|
||||||
for attr in dir(self)
|
|
||||||
if not attr.startswith('__') and not callable(getattr(self, attr))
|
|
||||||
}
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return str(self.get_data())
|
|
||||||
|
|
||||||
|
|
||||||
class VmFilterFlag(IntEnum):
|
class VmFilterFlag(IntEnum):
|
||||||
|
@ -111,26 +43,55 @@ class VmFilterFlag(IntEnum):
|
||||||
UserPrimaryGroupResources = -4 # Resources belonging to the user’s primary group
|
UserPrimaryGroupResources = -4 # Resources belonging to the user’s primary group
|
||||||
|
|
||||||
|
|
||||||
|
class VM:
|
||||||
|
def __init__(self, vm: dict):
|
||||||
|
self.id = vm.get('ID', None)
|
||||||
|
self.owner = {
|
||||||
|
'id': vm.get('UID', None),
|
||||||
|
'name': vm.get('UNAME', None),
|
||||||
|
'gname': vm.get('GNAME', None)
|
||||||
|
}
|
||||||
|
self.name = vm.get('NAME', None)
|
||||||
|
self.status = vm.get('STATE', None)
|
||||||
|
if self.status:
|
||||||
|
self.status = VMState(int(self.status)).name.lower()
|
||||||
|
|
||||||
|
template = vm['TEMPLATE']
|
||||||
|
|
||||||
|
self.disk = put_under_list(template.get('DISK', []))
|
||||||
|
self.graphics = template.get('GRAPHICS', {})
|
||||||
|
self.memory = template.get('MEMORY', None)
|
||||||
|
self.nic = put_under_list(template.get('NIC', []))
|
||||||
|
self.vcpu = template.get('VCPU', None)
|
||||||
|
self.host = {
|
||||||
|
'name': ((vm.get('HISTORY_RECORDS', {}) or {}).get('HISTORY', {}) or {}).get('HOSTNAME', None),
|
||||||
|
'id': ((vm.get('HISTORY_RECORDS', {}) or {}).get('HISTORY', {}) or {}).get('HID', None),
|
||||||
|
}
|
||||||
|
self.snapshots = put_under_list(vm.get('SNAPSHOTS', []))
|
||||||
|
|
||||||
|
def get_data(self):
|
||||||
|
return {
|
||||||
|
attr: getattr(self, attr)
|
||||||
|
for attr in dir(self)
|
||||||
|
if not attr.startswith('__') and not callable(getattr(self, attr))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
VM_STATES = list(pyone.VM_STATE)
|
with RPCClient('https://opennebula.ungleich.ch:2634/RPC2') as rpc_client:
|
||||||
START_ID = -1 # First id whatever it is
|
success, response, *_ = rpc_client.one.vmpool.infoextended(
|
||||||
END_ID = -1 # Last id whatever it is
|
config['oca']['client_secrets'], VmFilterFlag.AllResources.value, START_ID, END_ID, ALL_VM_STATES
|
||||||
|
)
|
||||||
|
if success:
|
||||||
|
vms = json.loads(json.dumps(parse(response)))['VM_POOL']['VM']
|
||||||
|
for i, vm in enumerate(vms):
|
||||||
|
vm_id = vm['ID']
|
||||||
|
etcd_client.put(f'/opennebula/vm/{vm_id}', vm)
|
||||||
|
|
||||||
# Get VMs in all kind of states
|
parsed_vm = VM(vm)
|
||||||
|
etcd_client.put(f'/opennebula/parsed_vm/{parsed_vm.id}', parsed_vm.get_data())
|
||||||
# vms is a list of lists
|
else:
|
||||||
vms = [
|
print(response)
|
||||||
one_client.vmpool.infoextended(VmFilterFlag.AllResources.value, START_ID, END_ID, vm_state).VM
|
|
||||||
for vm_state in VM_STATES
|
|
||||||
]
|
|
||||||
# Take out elements from nested lists and put them into the original list
|
|
||||||
# forming a nice flat list
|
|
||||||
vms = list(reduce(lambda n, n_1: n + n_1, vms))
|
|
||||||
print('Total VMs:', len(vms))
|
|
||||||
for i, _vm in enumerate(vms):
|
|
||||||
vm = VM(_vm)
|
|
||||||
etcd_client.put('/opennebula/vm/{}'.format(vm.id), vm.get_data())
|
|
||||||
print(i, end=' ')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
Loading…
Reference in a new issue