Skip to content

Commit

Permalink
Update hypervisor resource query
Browse files Browse the repository at this point in the history
Some fields from the hypervisor api have been deprecated since wallaby: https://specs.openstack.org/openstack/nova-specs/specs/wallaby/implemented/modernize-os-hypervisors-api.html
Change to using placement api to get hypervisor resource (vcpu, memory, disk) usage and totals
Remove deprecated running_vms field from hypervisor propertiescan use server query instead
  • Loading branch information
gmatthews20 committed Dec 5, 2024
1 parent 35f5d24 commit c387001
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 15 deletions.
38 changes: 27 additions & 11 deletions openstackquery/enums/props/hypervisor_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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"],
Expand All @@ -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"
],
Expand Down
2 changes: 1 addition & 1 deletion openstackquery/mappings/hypervisor_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
]

Expand Down
54 changes: 51 additions & 3 deletions openstackquery/runners/hypervisor_runner.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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,
Expand All @@ -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)
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pylint
openstacksdk
pre-commit
tabulate
osc-placement

0 comments on commit c387001

Please sign in to comment.