import json import uncloud.secrets as secrets from xmlrpc.client import ServerProxy as RPCClient from django.core.management.base import BaseCommand from xmltodict import parse from enum import IntEnum from opennebula.models import VM as VMModel from uncloud_vm.models import VMHost from django_auth_ldap.backend import LDAPBackend class HostStates(IntEnum): """ The following flags are copied from https://docs.opennebula.org/5.8/integration/system_interfaces/api.html#schemas-for-host """ INIT = 0 # Initial state for enabled hosts MONITORING_MONITORED = 1 # Monitoring the host (from monitored) MONITORED = 2 # The host has been successfully monitored ERROR = 3 # An error ocurrer while monitoring the host DISABLED = 4 # The host is disabled MONITORING_ERROR = 5 # Monitoring the host (from error) MONITORING_INIT = 6 # Monitoring the host (from init) MONITORING_DISABLED = 7 # Monitoring the host (from disabled) OFFLINE = 8 # The host is totally offline class Command(BaseCommand): help = 'Syncronize Host information from OpenNebula' def add_arguments(self, parser): pass def handle(self, *args, **options): with RPCClient(secrets.OPENNEBULA_URL) as rpc_client: success, response, *_ = rpc_client.one.hostpool.info(secrets.OPENNEBULA_USER_PASS) if success: response = json.loads(json.dumps(parse(response))) host_pool = response.get('HOST_POOL', {}).get('HOST', {}) for host in host_pool: host_share = host.get('HOST_SHARE', {}) host_name = host.get('NAME') state = int(host.get('STATE', HostStates.OFFLINE.value)) if state == HostStates.MONITORED: status = 'active' elif state == HostStates.DISABLED: status = 'disabled' else: status = 'unusable' usable_cores = host_share.get('TOTAL_CPU') usable_ram_in_kb = int(host_share.get('TOTAL_MEM', 0)) usable_ram_in_gb = int(usable_ram_in_kb / 2 ** 20) vms = host.get('VMS', {}) or {} vms = vms.get('ID', []) or [] vms = ','.join(vms) VMHost.objects.update_or_create( hostname=host_name, defaults={ 'usable_cores': usable_cores, 'usable_ram_in_gb': usable_ram_in_gb, 'status': status, 'vms': vms } ) else: print(response)