Violet Kurtz 006e35509d Moved hypervisor to the SDK
Change-Id: Ie955fb4d27c30e044626732a1f3e0f141cb85aa5
2022-11-09 19:33:54 +00:00

257 lines
9.0 KiB
Python

# Copyright 2012-2013 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""Hypervisor action implementations"""
import json
import re
from novaclient import exceptions as nova_exceptions
from openstack import utils as sdk_utils
from osc_lib.cli import format_columns
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.i18n import _
def _get_hypervisor_columns(item, client):
column_map = {'name': 'hypervisor_hostname'}
hidden_columns = ['location', 'servers']
if sdk_utils.supports_microversion(client, '2.88'):
hidden_columns.extend([
'current_workload',
'disk_available',
'local_disk_free',
'local_disk_size',
'local_disk_used',
'memory_free',
'memory_size',
'memory_used',
'running_vms',
'vcpus_used',
'vcpus',
])
else:
column_map.update({
'disk_available': 'disk_available_least',
'local_disk_free': 'free_disk_gb',
'local_disk_size': 'local_gb',
'local_disk_used': 'local_gb_used',
'memory_free': 'free_ram_mb',
'memory_used': 'memory_mb_used',
'memory_size': 'memory_mb',
})
return utils.get_osc_show_columns_for_sdk_resource(
item, column_map, hidden_columns)
class ListHypervisor(command.Lister):
_description = _("List hypervisors")
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
parser.add_argument(
'--matching',
metavar='<hostname>',
help=_("Filter hypervisors using <hostname> substring")
)
parser.add_argument(
'--marker',
metavar='<marker>',
help=_(
"The UUID of the last hypervisor of the previous page; "
"displays list of hypervisors after 'marker'. "
"(supported with --os-compute-api-version 2.33 or above)"
),
)
parser.add_argument(
'--limit',
metavar='<limit>',
type=int,
help=_(
"Maximum number of hypervisors to display. Note that there "
"is a configurable max limit on the server, and the limit "
"that is used will be the minimum of what is requested "
"here and what is configured in the server. "
"(supported with --os-compute-api-version 2.33 or above)"
),
)
parser.add_argument(
'--long',
action='store_true',
help=_("List additional fields in output")
)
return parser
def take_action(self, parsed_args):
compute_client = self.app.client_manager.sdk_connection.compute
list_opts = {}
if parsed_args.matching and (parsed_args.marker or parsed_args.limit):
msg = _(
'--matching is not compatible with --marker or --limit'
)
raise exceptions.CommandError(msg)
if parsed_args.marker:
if not sdk_utils.supports_microversion(compute_client, '2.33'):
msg = _(
'--os-compute-api-version 2.33 or greater is required to '
'support the --marker option'
)
raise exceptions.CommandError(msg)
list_opts['marker'] = parsed_args.marker
if parsed_args.limit:
if not sdk_utils.supports_microversion(compute_client, '2.33'):
msg = _(
'--os-compute-api-version 2.33 or greater is required to '
'support the --limit option'
)
raise exceptions.CommandError(msg)
list_opts['limit'] = parsed_args.limit
column_headers = (
"ID",
"Hypervisor Hostname",
"Hypervisor Type",
"Host IP",
"State"
)
columns = (
'id',
'name',
'hypervisor_type',
'host_ip',
'state'
)
if parsed_args.long:
if not sdk_utils.supports_microversion(compute_client, '2.88'):
column_headers += (
'vCPUs Used',
'vCPUs',
'Memory MB Used',
'Memory MB'
)
columns += (
'vcpus_used',
'vcpus',
'memory_used',
'memory_size'
)
if parsed_args.matching:
data = compute_client.find_hypervisor(
parsed_args.matching, ignore_missing=False)
else:
data = compute_client.hypervisors(**list_opts, details=True)
return (
column_headers,
(utils.get_item_properties(s, columns) for s in data),
)
class ShowHypervisor(command.ShowOne):
_description = _("Display hypervisor details")
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
parser.add_argument(
"hypervisor",
metavar="<hypervisor>",
help=_("Hypervisor to display (name or ID)")
)
return parser
def take_action(self, parsed_args):
compute_client = self.app.client_manager.sdk_connection.compute
hypervisor = compute_client.find_hypervisor(
parsed_args.hypervisor, ignore_missing=False).copy()
# Some of the properties in the hypervisor object need to be processed
# before they get reported to the user. We spend this section
# extracting the relevant details to be reported by modifying our
# copy of the hypervisor object.
aggregates = compute_client.aggregates()
hypervisor['aggregates'] = list()
service_details = hypervisor['service_details']
if aggregates:
# Hypervisors in nova cells are prefixed by "<cell>@"
if "@" in service_details['host']:
cell, service_host = service_details['host'].split('@', 1)
else:
cell = None
service_host = service_details['host']
if cell:
# The host aggregates are also prefixed by "<cell>@"
member_of = [aggregate.name
for aggregate in aggregates
if cell in aggregate.name and
service_host in aggregate.hosts]
else:
member_of = [aggregate.name
for aggregate in aggregates
if service_host in aggregate.hosts]
hypervisor['aggregates'] = member_of
try:
if sdk_utils.supports_microversion(compute_client, '2.88'):
uptime = hypervisor['uptime'] or ''
del hypervisor['uptime']
else:
del hypervisor['uptime']
uptime = compute_client.get_hypervisor_uptime(
hypervisor['id'])['uptime']
# Extract data from uptime value
# format: 0 up 0, 0 users, load average: 0, 0, 0
# example: 17:37:14 up 2:33, 3 users,
# load average: 0.33, 0.36, 0.34
m = re.match(
r"\s*(.+)\sup\s+(.+),\s+(.+)\susers?,\s+load average:\s(.+)",
uptime)
if m:
hypervisor['host_time'] = m.group(1)
hypervisor['uptime'] = m.group(2)
hypervisor['users'] = m.group(3)
hypervisor['load_average'] = m.group(4)
except nova_exceptions.HTTPNotImplemented:
pass
hypervisor['service_id'] = service_details['id']
hypervisor['service_host'] = service_details['host']
del hypervisor['service_details']
if not sdk_utils.supports_microversion(compute_client, '2.28'):
# microversion 2.28 transformed this to a JSON blob rather than a
# string; on earlier fields, do this manually
hypervisor['cpu_info'] = json.loads(hypervisor['cpu_info'] or '{}')
display_columns, columns = _get_hypervisor_columns(
hypervisor, compute_client)
data = utils.get_dict_properties(
hypervisor, columns,
formatters={
'cpu_info': format_columns.DictColumn,
})
return display_columns, data