From add1a1f865fc59e6f49a712eeea970c7c2793cc6 Mon Sep 17 00:00:00 2001 From: Christopher Kreft Date: Sat, 18 Apr 2026 15:04:33 +0200 Subject: [PATCH] fix(perf): validate metric arguments and missing instances --- checkvsphere/vcmd/datastores.py | 7 +++++++ checkvsphere/vcmd/perf.py | 15 ++++++++------- checkvsphere/vcmd/vmguestfs.py | 3 ++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/checkvsphere/vcmd/datastores.py b/checkvsphere/vcmd/datastores.py index 70c0f12..d93f886 100644 --- a/checkvsphere/vcmd/datastores.py +++ b/checkvsphere/vcmd/datastores.py @@ -70,6 +70,12 @@ def range_in_bytes(r: Range, uom): ":" + ('' if end == float('+inf') else str(end)) args = None +UNIT_METRICS = ('B', 'kB', 'MB', 'GB') +METRIC_CHOICES = ( + ['usage'] + + [metric for metric in ('free', 'used', 'capacity')] + + [f"{metric}_{unit}" for metric in ('free', 'used', 'capacity') for unit in UNIT_METRICS] +) def run(): global args @@ -85,6 +91,7 @@ def run(): 'options': { 'action': 'store', 'default': 'usage', + 'choices': METRIC_CHOICES, 'help': 'The metric to apply the thresholds on, defaults to `usage`, can be: ' 'usage (in percent), free and used. ' 'free and used are measured in bytes. You can one of these suffixes: ' diff --git a/checkvsphere/vcmd/perf.py b/checkvsphere/vcmd/perf.py index 26314a9..690bee7 100644 --- a/checkvsphere/vcmd/perf.py +++ b/checkvsphere/vcmd/perf.py @@ -80,17 +80,18 @@ def run(): check = Check() check.set_threshold(warning=args.warning, critical=args.critical) - args._si = service_instance.connect(args) - try: vimtype = getattr(vim, args.vimtype) except: raise Exception(f"vim.{args.vimtype} is not known") - try: - args.perfcounter.split(":", 2) - except: - raise Exception("perfcounter must be composed as groupName:perfName:rollupType") + parts = args.perfcounter.split(":") + if len(parts) != 3 or any(not part for part in parts): + raise CheckVsphereException( + "perfcounter must be composed as groupName:perfName:rollupType" + ) + + args._si = service_instance.connect(args) (counter, metricId) = get_metric( args._si.content.perfManager, args.perfcounter, args.perfinstance @@ -230,7 +231,7 @@ def get_argparser(): 'options': { 'action': 'store', 'default': '', - 'help': 'the instance of of the metric to monitor. defaults to empty string, ' + 'help': 'the instance of the metric to monitor. defaults to empty string, ' 'which is not always available but means an aggregated value over all instances', }, } diff --git a/checkvsphere/vcmd/vmguestfs.py b/checkvsphere/vcmd/vmguestfs.py index d71e7b9..b26f27d 100644 --- a/checkvsphere/vcmd/vmguestfs.py +++ b/checkvsphere/vcmd/vmguestfs.py @@ -30,7 +30,7 @@ isallowed, isbanned, ) -from checkvsphere.vcmd.datastores import Space, range_in_bytes +from checkvsphere.vcmd.datastores import METRIC_CHOICES, Space, range_in_bytes args = None @@ -49,6 +49,7 @@ def run(): "options": { "action": "store", "default": "usage", + "choices": METRIC_CHOICES, "help": "The metric to apply the thresholds on, defaults to `usage`, can be: " "usage (in percent), free and used. " "free and used are measured in bytes. You can use one of these suffixes: "