Skip to content

Commit 23fbbc6

Browse files
committed
added filtering for devices, bug fix + updated utest
1 parent 6d60420 commit 23fbbc6

File tree

3 files changed

+51
-32
lines changed

3 files changed

+51
-32
lines changed

nodescraper/plugins/inband/storage/analyzer_args.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,5 @@
3030

3131
class StorageAnalyzerArgs(BaseModel):
3232
min_required_free_space_abs: Optional[str] = None
33-
min_required_free_space_prct: int = 10
33+
min_required_free_space_prct: Optional[int] = None
34+
ignore_devices: Optional[list] = []

nodescraper/plugins/inband/storage/storage_analyzer.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,23 @@ def analyze_data(
5353
"""
5454
if args is None:
5555
args = StorageAnalyzerArgs()
56+
if (
57+
args.min_required_free_space_abs is None
58+
and args.min_required_free_space_prct is None
59+
):
60+
args.min_required_free_space_prct = 10
61+
self.logger.warning(
62+
"No defaults provided for storage analyzer arguments. Setting min_required_free_space_prct=10"
63+
)
5664

5765
if not data.storage_data:
5866
self.result.message = "No storage data available"
5967
self.result.status = ExecutionStatus.NOT_RAN
6068
return self.result
6169

6270
for device_name, device_data in data.storage_data.items():
71+
if args.ignore_devices and device_name in args.ignore_devices:
72+
continue
6373
condition = False
6474
if args.min_required_free_space_abs:
6575
min_free_abs = convert_to_bytes(args.min_required_free_space_abs)
@@ -69,35 +79,29 @@ def analyze_data(
6979
else:
7080
condition = True
7181

72-
free_prct = 100 - device_data.percent
73-
condition = condition and (free_prct < args.min_required_free_space_prct)
82+
if args.min_required_free_space_prct:
83+
free_prct = 100 - device_data.percent
84+
condition = condition and (free_prct > args.min_required_free_space_prct)
7485

7586
if condition:
7687
self.result.message = f"'{device_name}' has {bytes_to_human_readable(device_data.free)} available, {device_data.percent}% used"
7788
self.result.status = ExecutionStatus.OK
78-
break
7989
else:
8090
self.result.message = "Not enough disk storage!"
8191
self.result.status = ExecutionStatus.ERROR
82-
# find the device with the largest total storage, and its free space
83-
largest_device = max(
84-
data.storage_data,
85-
key=lambda x: convert_to_bytes(str(data.storage_data[x].total)),
86-
)
87-
largest_free = data.storage_data[largest_device].free
88-
largest_percent = data.storage_data[largest_device].percent
89-
largest_used = data.storage_data[largest_device].used
9092
event_data = {
91-
"largest_device": {
92-
"device": largest_device,
93-
"total": data.storage_data[largest_device].total,
94-
"free": largest_free,
95-
"percent": largest_percent,
93+
"offending_device": {
94+
"device": device_name,
95+
"total": device_data.total,
96+
"free": device_data.free,
97+
"percent": device_data.percent,
9698
},
9799
}
100+
device = convert_to_bytes(str(device_data.total))
101+
prct = device_data.percent
98102
self._log_event(
99103
category=EventCategory.STORAGE,
100-
description=f"{self.result.message} {bytes_to_human_readable(largest_used)} and {largest_percent}%, used on {largest_device}",
104+
description=f"{self.result.message} {bytes_to_human_readable(device)} and {prct}%, used on {device_name}",
101105
data=event_data,
102106
priority=EventPriority.CRITICAL,
103107
console_log=True,

test/unit/plugin/test_storage_analyzer.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,21 @@ def analyzer(system_info):
5757

5858

5959
def test_only_absolute_threshold_fails(analyzer, model_obj):
60-
args = StorageAnalyzerArgs(min_required_free_space_abs="1TB")
60+
args = StorageAnalyzerArgs(min_required_free_space_abs="800GB")
6161
result = analyzer.analyze_data(model_obj, args)
62-
assert result.status == ExecutionStatus.ERROR
63-
assert any(event.category == EventCategory.STORAGE.value for event in result.events)
64-
assert any(event.priority == EventPriority.CRITICAL for event in result.events)
62+
assert result.status == ExecutionStatus.OK
63+
assert "'/dev/nvme0n1p2' has 869.8GB available, 3.0% used" in result.message
6564

6665

6766
def test_only_percentage_threshold_fails(analyzer, model_obj):
68-
args = StorageAnalyzerArgs(min_required_free_space_prct=50)
67+
args = StorageAnalyzerArgs(min_required_free_space_prct=99)
6968
result = analyzer.analyze_data(model_obj, args)
7069
assert result.status == ExecutionStatus.ERROR
7170
assert any(event.category == EventCategory.STORAGE.value for event in result.events)
7271
assert any(event.priority == EventPriority.CRITICAL for event in result.events)
7372

7473

75-
def test_windows_nominal(system_info):
74+
def test_both_abs_and_prct_fail(system_info):
7675
system_info.os_family = OSFamily.WINDOWS
7776
analyzer = StorageAnalyzer(system_info=system_info)
7877

@@ -87,14 +86,29 @@ def test_windows_nominal(system_info):
8786
}
8887
)
8988

90-
args = StorageAnalyzerArgs(min_required_free_space_abs="10GB", min_required_free_space_prct=50)
89+
args = StorageAnalyzerArgs(min_required_free_space_abs="10GB", min_required_free_space_prct=96)
9190
result = analyzer.analyze_data(model, args)
92-
assert result.status == ExecutionStatus.OK
93-
assert " has 466.44GB available, 53.97% used" in result.message
94-
assert len(result.events) == 0
91+
assert result.status == ExecutionStatus.ERROR
92+
assert "Not enough disk storage!" in result.message
93+
assert len(result.events) == 1
94+
assert any(e.category == EventCategory.STORAGE.value for e in result.events)
95+
assert any(e.priority == EventPriority.CRITICAL for e in result.events)
9596

96-
args2 = StorageAnalyzerArgs(min_required_free_space_prct=40)
97+
args2 = StorageAnalyzerArgs(min_required_free_space_prct=40, min_required_dree_space_abs="1GB")
9798
result2 = analyzer.analyze_data(model, args2)
98-
assert result2.status == ExecutionStatus.ERROR
99-
assert any(e.category == EventCategory.STORAGE.value for e in result2.events)
100-
assert any(e.priority == EventPriority.CRITICAL for e in result2.events)
99+
assert result2.status == ExecutionStatus.OK
100+
101+
102+
def test_device_filter(analyzer, model_obj):
103+
model_obj.storage_data["some_device"] = DeviceStorageData(
104+
total=1000, free=100, used=900, percent=90
105+
)
106+
107+
args = StorageAnalyzerArgs(min_required_free_space_prct="20")
108+
result = analyzer.analyze_data(model_obj, args)
109+
assert result.status == ExecutionStatus.ERROR
110+
assert len(result.events) == 1
111+
112+
args2 = StorageAnalyzerArgs(min_required_free_space_prct="20", ignore_devices=["some_device"])
113+
result2 = analyzer.analyze_data(model_obj, args2)
114+
assert result2.status == ExecutionStatus.OK

0 commit comments

Comments
 (0)