diff --git a/openstackquery/enums/props/hypervisor_properties.py b/openstackquery/enums/props/hypervisor_properties.py index 452f4c2..b9fa5d3 100644 --- a/openstackquery/enums/props/hypervisor_properties.py +++ b/openstackquery/enums/props/hypervisor_properties.py @@ -22,7 +22,7 @@ class HypervisorProperties(PropEnum): HYPERVISOR_MEMORY_SIZE = auto() HYPERVISOR_MEMORY_USED = auto() HYPERVISOR_NAME = auto() - HYPERVISOR_SERVER_COUNT = auto() + # HYPERVISOR_SERVER_COUNT = auto() # Deprecated, use server query HYPERVISOR_STATE = auto() HYPERVISOR_STATUS = auto() HYPERVISOR_VCPUS = auto() @@ -57,7 +57,7 @@ def _get_aliases() -> Dict: "memory_mb_used", ], HypervisorProperties.HYPERVISOR_NAME: ["name", "host_name"], - HypervisorProperties.HYPERVISOR_SERVER_COUNT: ["running_vms"], + # HypervisorProperties.HYPERVISOR_SERVER_COUNT: ["running_vms"], HypervisorProperties.HYPERVISOR_STATE: ["state"], HypervisorProperties.HYPERVISOR_STATUS: ["status"], HypervisorProperties.HYPERVISOR_VCPUS: ["vcpus"], @@ -77,20 +77,36 @@ def get_prop_mapping(prop) -> Optional[PropFunc]: HypervisorProperties.HYPERVISOR_CURRENT_WORKLOAD: lambda a: a[ "current_workload" ], - HypervisorProperties.HYPERVISOR_DISK_FREE: lambda a: a["free_disk_gb"], - HypervisorProperties.HYPERVISOR_DISK_SIZE: lambda a: a["local_gb"], - HypervisorProperties.HYPERVISOR_DISK_USED: lambda a: a["local_gb_used"], + HypervisorProperties.HYPERVISOR_DISK_FREE: lambda a: a.resources.get( + "DISK_GB" + ).get("free", None), + HypervisorProperties.HYPERVISOR_DISK_SIZE: lambda a: a.resources.get( + "DISK_GB" + ).get("total", None), + HypervisorProperties.HYPERVISOR_DISK_USED: lambda a: a.resources.get( + "DISK_GB" + ).get("usage", None), HypervisorProperties.HYPERVISOR_ID: lambda a: a["id"], HypervisorProperties.HYPERVISOR_IP: lambda a: a["host_ip"], - HypervisorProperties.HYPERVISOR_MEMORY_FREE: lambda a: a["free_ram_mb"], - HypervisorProperties.HYPERVISOR_MEMORY_SIZE: lambda a: a["memory_mb"], - HypervisorProperties.HYPERVISOR_MEMORY_USED: lambda a: a["memory_mb_used"], + HypervisorProperties.HYPERVISOR_MEMORY_FREE: lambda a: a.resources.get( + "MEMORY_MB" + ).get("free", None), + HypervisorProperties.HYPERVISOR_MEMORY_SIZE: lambda a: a.resources.get( + "MEMORY_MB" + ).get("total", None), + HypervisorProperties.HYPERVISOR_MEMORY_USED: lambda a: a.resources.get( + "MEMORY_MB" + ).get("usage", None), HypervisorProperties.HYPERVISOR_NAME: lambda a: a["name"], - HypervisorProperties.HYPERVISOR_SERVER_COUNT: lambda a: a["runnning_vms"], + # HypervisorProperties.HYPERVISOR_SERVER_COUNT: lambda a: a["runnning_vms"], HypervisorProperties.HYPERVISOR_STATE: lambda a: a["state"], HypervisorProperties.HYPERVISOR_STATUS: lambda a: a["status"], - HypervisorProperties.HYPERVISOR_VCPUS: lambda a: a["vcpus"], - HypervisorProperties.HYPERVISOR_VCPUS_USED: lambda a: a["vcpus_used"], + HypervisorProperties.HYPERVISOR_VCPUS: lambda a: a.resources.get( + "VCPU" + ).get("total", None), + HypervisorProperties.HYPERVISOR_VCPUS_USED: lambda a: a.resources.get( + "VCPU" + ).get("usage", None), HypervisorProperties.HYPERVISOR_DISABLED_REASON: lambda a: a["service"][ "disabled_reason" ], diff --git a/openstackquery/mappings/hypervisor_mapping.py b/openstackquery/mappings/hypervisor_mapping.py index b38a625..daa556e 100644 --- a/openstackquery/mappings/hypervisor_mapping.py +++ b/openstackquery/mappings/hypervisor_mapping.py @@ -81,7 +81,7 @@ def get_client_side_handlers() -> QueryClientSideHandlers: HypervisorProperties.HYPERVISOR_MEMORY_FREE, HypervisorProperties.HYPERVISOR_VCPUS, HypervisorProperties.HYPERVISOR_VCPUS_USED, - HypervisorProperties.HYPERVISOR_SERVER_COUNT, + # HypervisorProperties.HYPERVISOR_SERVER_COUNT, # Deprecated, use server query HypervisorProperties.HYPERVISOR_CURRENT_WORKLOAD, ] diff --git a/openstackquery/runners/hypervisor_runner.py b/openstackquery/runners/hypervisor_runner.py index 8c7acdb..b7d2295 100644 --- a/openstackquery/runners/hypervisor_runner.py +++ b/openstackquery/runners/hypervisor_runner.py @@ -1,8 +1,11 @@ +import json import logging -from typing import Optional, List +from typing import Dict, List, Optional + from openstack.compute.v2.hypervisor import Hypervisor +from osc_placement.http import SessionClient as PlacementClient -from openstackquery.aliases import ServerSideFilters, OpenstackResourceObj +from openstackquery.aliases import OpenstackResourceObj, ServerSideFilters from openstackquery.openstack_connection import OpenstackConnection from openstackquery.runners.runner_utils import RunnerUtils from openstackquery.runners.runner_wrapper import RunnerWrapper @@ -26,6 +29,49 @@ def parse_meta_params(self, conn: OpenstackConnection, **kwargs): logger.debug("HypervisorQuery has no meta-params available") return super().parse_meta_params(conn, **kwargs) + def _populate_placement_info( + self, conn: OpenstackConnection, hypervisors: List + ) -> List: + """ + Adds resource usage stats to the hypervisors + :param conn: Openstack connecion + :param hypervisors: List of hypervisors + :return: List of hypervisors with additional resource usage stats + """ + client = PlacementClient( + api_version="1.6", + session=conn.session, + ks_filter={"service_type": "placement"}, + ) + + for hypervisor in hypervisors: + hypervisor.resources = self._get_usage_info(conn, client, hypervisor) + + return hypervisors + + def _get_usage_info( + self, conn: OpenstackConnection, client: PlacementClient, hypervisor: Hypervisor + ) -> Dict: + """ + Get usage stats from the openstack placement api + :param conn: Openstack connection + :param client: osc_placement session client + :param hypervisor: Openstack hypervisor + :return: resource usage for the hypervisor + """ + resources = conn.placement.resource_provider_inventories(hypervisor.id) + usages = client.request("get", f"/resource_providers/{hypervisor.id}/usages") + usages = json.loads(usages.text).get("usages") + usage_info = {} + for i in resources: + usage_info[i.resource_class] = { + "total": i.total, + "usage": usages.get(i.resource_class), + "free": i.total - usages.get(i.resource_class), + } + + return usage_info + # pylint: disable=unused-argument def run_query( self, @@ -49,6 +95,8 @@ def run_query( "running openstacksdk command conn.compute.hypervisors(%s)", ",".join(f"{key}={value}" for key, value in filter_kwargs.items()), ) - return RunnerUtils.run_paginated_query( + hypervisors = RunnerUtils.run_paginated_query( conn.compute.hypervisors, self._page_marker_prop_func, filter_kwargs ) + + return self._populate_placement_info(conn, hypervisors) diff --git a/requirements.txt b/requirements.txt index 26a32e7..418e4f7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ pylint openstacksdk pre-commit tabulate +osc-placement