Skip to content

Commit 4ce2e74

Browse files
committed
fix(perf): validate metric arguments and missing instances
1 parent 6177be0 commit 4ce2e74

3 files changed

Lines changed: 36 additions & 8 deletions

File tree

checkvsphere/vcmd/datastores.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ def range_in_bytes(r: Range, uom):
7070
":" + ('' if end == float('+inf') else str(end))
7171

7272
args = None
73+
UNIT_METRICS = ('B', 'kB', 'MB', 'GB')
74+
METRIC_CHOICES = (
75+
['usage']
76+
+ [metric for metric in ('free', 'used', 'capacity')]
77+
+ [f"{metric}_{unit}" for metric in ('free', 'used', 'capacity') for unit in UNIT_METRICS]
78+
)
7379

7480
def run():
7581
global args
@@ -85,6 +91,7 @@ def run():
8591
'options': {
8692
'action': 'store',
8793
'default': 'usage',
94+
'choices': METRIC_CHOICES,
8895
'help': 'The metric to apply the thresholds on, defaults to `usage`, can be: '
8996
'usage (in percent), free and used. '
9097
'free and used are measured in bytes. You can one of these suffixes: '

checkvsphere/vcmd/perf.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,18 @@ def run():
8080
check = Check()
8181
check.set_threshold(warning=args.warning, critical=args.critical)
8282

83-
args._si = service_instance.connect(args)
84-
8583
try:
8684
vimtype = getattr(vim, args.vimtype)
8785
except:
8886
raise Exception(f"vim.{args.vimtype} is not known")
8987

90-
try:
91-
args.perfcounter.split(":", 2)
92-
except:
93-
raise Exception("perfcounter must be composed as groupName:perfName:rollupType")
88+
parts = args.perfcounter.split(":")
89+
if len(parts) != 3 or any(not part for part in parts):
90+
raise CheckVsphereException(
91+
"perfcounter must be composed as groupName:perfName:rollupType"
92+
)
93+
94+
args._si = service_instance.connect(args)
9495

9596
(counter, metricId) = get_metric(
9697
args._si.content.perfManager, args.perfcounter, args.perfinstance
@@ -152,15 +153,24 @@ def run():
152153
code=check.check_threshold(val),
153154
message=f'Counter {args.perfcounter} on {args.vimtype}:{args.vimname or props["name"]} reported {val:.8g} {counterInfo["unit"]}',
154155
)
156+
check.exit(
157+
code=Status.UNKNOWN,
158+
message=(
159+
f"Counter {args.perfcounter} on {args.vimtype}:{args.vimname or props['name']} "
160+
"did not return an aggregate instance; maybe --perfinstance='*' helps"
161+
),
162+
)
155163
else:
156164
metrics_count = len(values.value)
165+
found_instance = False
157166
for instance in values.value:
158167
if metrics_count == 1 and instance.id.instance == '':
159168
raise CheckVsphereException("The perfcounter only returns an aggregate, maybe you want to use --perfinstance '' instead")
160169
if instance.id.instance == '':
161170
# ignore the aggregate if we query a specific or all instances
162171
continue
163172
if args.perfinstance == '*' or args.perfinstance == instance.id.instance:
173+
found_instance = True
164174
val = instance.value[0] * counterInfo['factor']
165175
check.add_perfdata(
166176
label=f'{instance.id.instance} {args.perfcounter}',
@@ -173,6 +183,16 @@ def run():
173183
f"'{instance.id.instance} {args.perfcounter}' has value {val:.8g} {counterInfo['unit']}",
174184
)
175185

186+
if not found_instance:
187+
check.exit(
188+
code=Status.UNKNOWN,
189+
message=(
190+
f"Counter {args.perfcounter} on {args.vimtype}:{args.vimname or props['name']} "
191+
f"did not return the requested instance '{args.perfinstance}'; "
192+
"maybe --perfinstance='*' helps to examine the available instances"
193+
),
194+
)
195+
176196
(code, message) = check.check_messages(separator='\n ')
177197
check.exit(code=code, message=message)
178198

@@ -230,7 +250,7 @@ def get_argparser():
230250
'options': {
231251
'action': 'store',
232252
'default': '',
233-
'help': 'the instance of of the metric to monitor. defaults to empty string, '
253+
'help': 'the instance of the metric to monitor. defaults to empty string, '
234254
'which is not always available but means an aggregated value over all instances',
235255
},
236256
}

checkvsphere/vcmd/vmguestfs.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
isallowed,
3131
isbanned,
3232
)
33-
from checkvsphere.vcmd.datastores import Space, range_in_bytes
33+
from checkvsphere.vcmd.datastores import METRIC_CHOICES, Space, range_in_bytes
3434

3535
args = None
3636

@@ -49,6 +49,7 @@ def run():
4949
"options": {
5050
"action": "store",
5151
"default": "usage",
52+
"choices": METRIC_CHOICES,
5253
"help": "The metric to apply the thresholds on, defaults to `usage`, can be: "
5354
"usage (in percent), free and used. "
5455
"free and used are measured in bytes. You can use one of these suffixes: "

0 commit comments

Comments
 (0)