ungleich-tools/opennebula-vm-etcd/put-vm-info-into-etcd.py

138 lines
3.8 KiB
Python
Raw Normal View History

import pyone
from enum import IntEnum
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):
for hostname, host in host_pool.items():
if vm_id in host['vms']:
return host
return None
def put_under_list(obj):
if not isinstance(obj, list):
return [obj]
return obj
class Snapshot:
def __init__(self, disk_id, snapshot):
self.active = bool(snapshot.ACTIVE)
self.date = snapshot.DATE
self.id = snapshot.ID
self.name = snapshot.NAME
self.size = snapshot.SIZE
self.disk_id = disk_id
def get_data(self):
return {
attr: getattr(self, attr)
for attr in dir(self)
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):
UIDUserResources = 0 # UID Users Resources
UserAndItsGroupsResources = -1 # Resources belonging to the user and any of his groups
AllResources = -2 # All resources
UserResources = -3 # Resources belonging to the user
UserPrimaryGroupResources = -4 # Resources belonging to the users primary group
def main():
VM_STATES = list(pyone.VM_STATE)
START_ID = -1 # First id whatever it is
END_ID = -1 # Last id whatever it is
# Get VMs in all kind of states
# vms is a list of lists
vms = [
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__":
main()