Add cluster detail list

Adds a command to show a list of details including health and item
counts for all configured clusters in the client.
This commit is contained in:
Joshua Boniface 2023-02-22 18:09:11 -05:00
parent 94d4ee5b9b
commit 8331b7ecd8
2 changed files with 218 additions and 21 deletions

View File

@ -183,7 +183,7 @@ def format_info(cluster_information, oformat):
) )
) )
ainformation.append( ainformation.append(
"{}PVC Version:{} {}".format( "{}PVC version:{} {}".format(
ansiprint.purple(), ansiprint.purple(),
ansiprint.end(), ansiprint.end(),
cluster_information.get("pvc_version", "N/A"), cluster_information.get("pvc_version", "N/A"),

View File

@ -134,7 +134,7 @@ def get_config(store_data, cluster=None):
config = dict() config = dict()
config["debug"] = False config["debug"] = False
config["cluster"] = cluster config["cluster"] = cluster
config["desctription"] = description config["description"] = description
config["api_host"] = "{}:{}".format(host, port) config["api_host"] = "{}:{}".format(host, port)
config["api_scheme"] = scheme config["api_scheme"] = scheme
config["api_key"] = api_key config["api_key"] = api_key
@ -382,8 +382,6 @@ def cluster_list(raw):
if not raw: if not raw:
# Display the data nicely # Display the data nicely
echo("Available clusters:")
echo("")
echo( echo(
"{bold}{name: <{name_length}} {description: <{description_length}} {address: <{address_length}} {port: <{port_length}} {scheme: <{scheme_length}} {api_key: <{api_key_length}}{end_bold}".format( "{bold}{name: <{name_length}} {description: <{description_length}} {address: <{address_length}} {port: <{port_length}} {scheme: <{scheme_length}} {api_key: <{api_key_length}}{end_bold}".format(
bold=ansiprint.bold(), bold=ansiprint.bold(),
@ -443,6 +441,202 @@ def cluster_list(raw):
echo(cluster) echo(cluster)
###############################################################################
# pvc cluster detail
###############################################################################
@click.command(name="detail", short_help="Show details of all available clusters.")
def cluster_detail():
"""
Show quick details of all PVC clusters configured in this CLI instance.
"""
# Get the existing data
clusters = get_store(store_path)
cluster_details_list = list()
echo("Gathering information from clusters... ", nl=False)
for cluster in clusters:
_store_data = get_store(store_path)
cluster_config = get_config(_store_data, cluster=cluster)
retcode, retdata = pvc_cluster.get_info(cluster_config)
if retcode == 0:
retdata = None
cluster_details = {"config": cluster_config, "data": retdata}
cluster_details_list.append(cluster_details)
echo("done.")
echo("")
# Find the lengths of each column
name_length = 5
description_length = 12
health_length = 7
primary_node_length = 8
pvc_version_length = 8
nodes_length = 6
vms_length = 4
networks_length = 9
osds_length = 5
pools_length = 6
volumes_length = 8
snapshots_length = 10
for cluster_details in cluster_details_list:
_name_length = len(cluster_details["config"]["cluster"]) + 1
if _name_length > name_length:
name_length = _name_length
_description_length = len(cluster_details["config"]["description"]) + 1
if _description_length > description_length:
description_length = _description_length
if cluster_details["data"] is None:
continue
_health_length = (
len(str(cluster_details["data"]["cluster_health"]["health"]) + "%") + 1
)
if _health_length > health_length:
health_length = _health_length
_primary_node_length = len(cluster_details["data"]["primary_node"]) + 1
if _primary_node_length > primary_node_length:
primary_node_length = _primary_node_length
_pvc_version_length = len(cluster_details["data"]["pvc_version"]) + 1
if _pvc_version_length > pvc_version_length:
pvc_version_length = _pvc_version_length
_nodes_length = len(str(cluster_details["data"]["nodes"]["total"])) + 1
if _nodes_length > nodes_length:
nodes_length = _nodes_length
_vms_length = len(str(cluster_details["data"]["vms"]["total"])) + 1
if _vms_length > vms_length:
vms_length = _vms_length
_networks_length = len(str(cluster_details["data"]["networks"])) + 1
if _networks_length > networks_length:
networks_length = _networks_length
_osds_length = len(str(cluster_details["data"]["osds"]["total"])) + 1
if _osds_length > osds_length:
osds_length = _osds_length
_pools_length = len(str(cluster_details["data"]["pools"])) + 1
if _pools_length > pools_length:
pools_length = _pools_length
_volumes_length = len(str(cluster_details["data"]["volumes"])) + 1
if _volumes_length > volumes_length:
volumes_length = _volumes_length
_snapshots_length = len(str(cluster_details["data"]["snapshots"])) + 1
if _snapshots_length > snapshots_length:
snapshots_length = _snapshots_length
# Display the data nicely
echo(
"{bold}{name: <{name_length}} {description: <{description_length}} {health: <{health_length}} {primary_node: <{primary_node_length}} {pvc_version: <{pvc_version_length}} {nodes: <{nodes_length}} {vms: <{vms_length}} {networks: <{networks_length}} {osds: <{osds_length}} {pools: <{pools_length}} {volumes: <{volumes_length}} {snapshots: <{snapshots_length}}{end_bold}".format(
bold=ansiprint.bold(),
end_bold=ansiprint.end(),
name="Name",
name_length=name_length,
description="Description",
description_length=description_length,
health="Health",
health_length=health_length,
primary_node="Primary",
primary_node_length=primary_node_length,
pvc_version="Version",
pvc_version_length=pvc_version_length,
nodes="Nodes",
nodes_length=nodes_length,
vms="VMs",
vms_length=vms_length,
networks="Networks",
networks_length=networks_length,
osds="OSDs",
osds_length=osds_length,
pools="Pools",
pools_length=pools_length,
volumes="Volumes",
volumes_length=volumes_length,
snapshots="Snapshots",
snapshots_length=snapshots_length,
)
)
for cluster_details in cluster_details_list:
if cluster_details["data"] is None:
health_colour = ansiprint.blue()
name = cluster_details["config"]["cluster"]
description = cluster_details["config"]["description"]
health = "N/A"
primary_node = "N/A"
pvc_version = "N/A"
nodes = "N/A"
vms = "N/A"
networks = "N/A"
osds = "N/A"
pools = "N/A"
volumes = "N/A"
snapshots = "N/A"
else:
if cluster_details["data"]["cluster_health"]["health"] > 90:
health_colour = ansiprint.green()
elif cluster_details["data"]["cluster_health"]["health"] > 50:
health_colour = ansiprint.yellow()
else:
health_colour = ansiprint.red()
name = cluster_details["config"]["cluster"]
description = cluster_details["config"]["description"]
health = str(cluster_details["data"]["cluster_health"]["health"]) + "%"
primary_node = cluster_details["data"]["primary_node"]
pvc_version = cluster_details["data"]["pvc_version"]
nodes = str(cluster_details["data"]["nodes"]["total"])
vms = str(cluster_details["data"]["vms"]["total"])
networks = str(cluster_details["data"]["networks"])
osds = str(cluster_details["data"]["osds"]["total"])
pools = str(cluster_details["data"]["pools"])
volumes = str(cluster_details["data"]["volumes"])
snapshots = str(cluster_details["data"]["snapshots"])
echo(
"{name: <{name_length}} {description: <{description_length}} {health_colour}{health: <{health_length}}{end_colour} {primary_node: <{primary_node_length}} {pvc_version: <{pvc_version_length}} {nodes: <{nodes_length}} {vms: <{vms_length}} {networks: <{networks_length}} {osds: <{osds_length}} {pools: <{pools_length}} {volumes: <{volumes_length}} {snapshots: <{snapshots_length}}".format(
health_colour=health_colour,
end_colour=ansiprint.end(),
name=name,
name_length=name_length,
description=description,
description_length=description_length,
health=health,
health_length=health_length,
primary_node=primary_node,
primary_node_length=primary_node_length,
pvc_version=pvc_version,
pvc_version_length=pvc_version_length,
nodes=nodes,
nodes_length=nodes_length,
vms=vms,
vms_length=vms_length,
networks=networks,
networks_length=networks_length,
osds=osds,
osds_length=osds_length,
pools=pools,
pools_length=pools_length,
volumes=volumes,
volumes_length=volumes_length,
snapshots=snapshots,
snapshots_length=snapshots_length,
)
)
# Validate that the cluster is set for a given command # Validate that the cluster is set for a given command
def cluster_req(function): def cluster_req(function):
@wraps(function) @wraps(function)
@ -452,6 +646,24 @@ def cluster_req(function):
'No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.' 'No cluster specified and no local pvcapid.yaml configuration found. Use "pvc cluster" to add a cluster API to connect to.'
) )
exit(1) exit(1)
if not config["quiet"]:
if config["api_scheme"] == "https" and not config["verify_ssl"]:
ssl_unverified_msg = " (unverified)"
else:
ssl_unverified_msg = ""
echo(
'Using cluster "{}" - Host: "{}" Scheme: "{}{}" Prefix: "{}"'.format(
config["cluster"],
config["api_host"],
config["api_scheme"],
ssl_unverified_msg,
config["api_prefix"],
),
err=True,
)
echo("", err=True)
return function(*args, **kwargs) return function(*args, **kwargs)
return validate_cluster return validate_cluster
@ -5896,23 +6108,7 @@ def cli(_cluster, _debug, _quiet, _unsafe, _colour):
config["debug"] = _debug config["debug"] = _debug
config["unsafe"] = _unsafe config["unsafe"] = _unsafe
config["colour"] = _colour config["colour"] = _colour
config["quiet"] = _quiet
if not _quiet:
if config["api_scheme"] == "https" and not config["verify_ssl"]:
ssl_unverified_msg = " (unverified)"
else:
ssl_unverified_msg = ""
echo(
'Using cluster "{}" - Host: "{}" Scheme: "{}{}" Prefix: "{}"'.format(
config["cluster"],
config["api_host"],
config["api_scheme"],
ssl_unverified_msg,
config["api_prefix"],
),
err=True,
)
echo("", err=True)
audit() audit()
@ -5923,6 +6119,7 @@ def cli(_cluster, _debug, _quiet, _unsafe, _colour):
cli_cluster.add_command(cluster_add) cli_cluster.add_command(cluster_add)
cli_cluster.add_command(cluster_remove) cli_cluster.add_command(cluster_remove)
cli_cluster.add_command(cluster_list) cli_cluster.add_command(cluster_list)
cli_cluster.add_command(cluster_detail)
cli_node.add_command(node_secondary) cli_node.add_command(node_secondary)
cli_node.add_command(node_primary) cli_node.add_command(node_primary)