Skip to content

Commit dff2092

Browse files
committed
refactor: Address code review feedback (docstrings, timeouts, complexity)
1 parent 95215f7 commit dff2092

File tree

3 files changed

+92
-73
lines changed

3 files changed

+92
-73
lines changed

cortex/health/checks/disk.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,38 @@
22
from ..monitor import HealthCheck, CheckResult
33

44
class DiskCheck(HealthCheck):
5+
"""Check root filesystem disk usage."""
6+
57
def run(self) -> CheckResult:
6-
total, used, free = shutil.disk_usage("/")
7-
# Calculate usage percentage
8+
"""
9+
Calculate disk usage percentage.
10+
11+
Returns:
12+
CheckResult based on usage thresholds.
13+
"""
14+
# Use _ for unused variable (free space)
15+
total, used, _ = shutil.disk_usage("/")
816
usage_percent = (used / total) * 100
917

1018
score = 100
1119
status = "OK"
12-
details = f"{usage_percent:.1f}% Used"
1320
rec = None
14-
15-
# Scoring logic (Spec compliant)
21+
1622
if usage_percent > 90:
1723
score = 0
1824
status = "CRITICAL"
19-
rec = "Clean package cache (+50 pts)"
25+
rec = "Clean up disk space immediately"
2026
elif usage_percent > 80:
2127
score = 50
2228
status = "WARNING"
23-
rec = "Clean package cache (+10 pts)"
24-
29+
rec = "Consider cleaning up disk space"
30+
2531
return CheckResult(
26-
name="Disk Space",
32+
name="Disk Usage",
2733
category="disk",
2834
score=score,
2935
status=status,
30-
details=details,
36+
details=f"{usage_percent:.1f}% used",
3137
recommendation=rec,
32-
weight=0.15 # 15%
38+
weight=0.20
3339
)

cortex/health/checks/security.py

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,32 @@
33
from ..monitor import HealthCheck, CheckResult
44

55
class SecurityCheck(HealthCheck):
6+
"""Check security configuration including firewall and SSH settings."""
7+
68
def run(self) -> CheckResult:
9+
"""
10+
Run security checks for firewall status and SSH configuration.
11+
12+
Returns:
13+
CheckResult with security score based on detected issues.
14+
"""
715
score = 100
816
issues = []
917
recommendations = []
1018

1119
# 1. Firewall (UFW) Check
12-
ufw_active = False
13-
try:
14-
# Add timeout to prevent hanging (Fixes Reliability Issue)
15-
res = subprocess.run(
16-
["systemctl", "is-active", "ufw"],
17-
capture_output=True,
18-
text=True,
19-
timeout=5
20-
)
21-
# Fix: Use exact match to avoid matching "inactive" which contains "active"
22-
if res.returncode == 0 and res.stdout.strip() == "active":
23-
ufw_active = True
24-
except subprocess.TimeoutExpired:
25-
pass # Command timed out, treat as inactive or unavailable
26-
except FileNotFoundError:
27-
pass # Environment without systemctl (e.g., Docker or non-systemd)
28-
except Exception:
29-
pass # Generic error protection
30-
20+
ufw_active, ufw_issue, ufw_rec = self._check_firewall()
3121
if not ufw_active:
32-
score = 0 # Spec: 0 points if Firewall is inactive
33-
issues.append("Firewall Inactive")
34-
recommendations.append("Enable UFW Firewall")
22+
score = 0
23+
issues.append(ufw_issue)
24+
recommendations.append(ufw_rec)
3525

3626
# 2. SSH Root Login Check
37-
try:
38-
ssh_config = "/etc/ssh/sshd_config"
39-
if os.path.exists(ssh_config):
40-
with open(ssh_config, 'r') as f:
41-
for line in f:
42-
line = line.strip()
43-
# Check for uncommented PermitRootLogin yes
44-
if line.startswith("PermitRootLogin") and "yes" in line.split():
45-
score -= 50
46-
issues.append("Root SSH Allowed")
47-
recommendations.append("Disable SSH Root Login in sshd_config")
48-
break
49-
except PermissionError:
50-
pass # Cannot read config, skip check
51-
except Exception:
52-
pass # Generic error protection
27+
ssh_penalty, ssh_issue, ssh_rec = self._check_ssh_root_login()
28+
if ssh_penalty > 0:
29+
score -= ssh_penalty
30+
issues.append(ssh_issue)
31+
recommendations.append(ssh_rec)
5332

5433
status = "OK"
5534
if score < 50: status = "CRITICAL"
@@ -63,4 +42,35 @@ def run(self) -> CheckResult:
6342
details=", ".join(issues) if issues else "Secure",
6443
recommendation=", ".join(recommendations) if recommendations else None,
6544
weight=0.35
66-
)
45+
)
46+
47+
def _check_firewall(self):
48+
"""Check if UFW is active."""
49+
try:
50+
res = subprocess.run(
51+
["systemctl", "is-active", "ufw"],
52+
capture_output=True,
53+
text=True,
54+
timeout=10
55+
)
56+
if res.returncode == 0 and res.stdout.strip() == "active":
57+
return True, None, None
58+
except (subprocess.TimeoutExpired, FileNotFoundError, Exception):
59+
pass
60+
61+
return False, "Firewall Inactive", "Enable UFW Firewall"
62+
63+
def _check_ssh_root_login(self):
64+
"""Check for PermitRootLogin yes in sshd_config."""
65+
try:
66+
ssh_config = "/etc/ssh/sshd_config"
67+
if os.path.exists(ssh_config):
68+
with open(ssh_config, 'r') as f:
69+
for line in f:
70+
line = line.strip()
71+
if line.startswith("PermitRootLogin") and "yes" in line.split():
72+
return 50, "Root SSH Allowed", "Disable SSH Root Login in sshd_config"
73+
except (PermissionError, Exception):
74+
pass
75+
76+
return 0, None, None

cortex/health/checks/updates.py

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,58 @@
22
from ..monitor import HealthCheck, CheckResult
33

44
class UpdateCheck(HealthCheck):
5+
"""Check for pending system updates and security patches."""
6+
57
def run(self) -> CheckResult:
8+
"""
9+
Check for available updates using apt.
10+
11+
Returns:
12+
CheckResult with score based on pending updates.
13+
"""
614
score = 100
715
pkg_count = 0
816
sec_count = 0
9-
rec = None
1017

11-
# Parse apt list --upgradable
1218
try:
13-
# Execute safely without pipeline
19+
# Add timeout to prevent hangs
1420
res = subprocess.run(
1521
["apt", "list", "--upgradable"],
16-
capture_output=True, text=True
22+
capture_output=True,
23+
text=True,
24+
timeout=30
1725
)
18-
1926
lines = res.stdout.splitlines()
20-
# Skip first line "Listing..."
27+
28+
# apt list output header usually takes first line
2129
for line in lines[1:]:
2230
if line.strip():
23-
pkg_count += 1
2431
if "security" in line.lower():
2532
sec_count += 1
33+
else:
34+
pkg_count += 1
2635

2736
# Scoring
28-
score -= (pkg_count * 2) # -2 pts per normal package
29-
score -= (sec_count * 10) # -10 pts per security package
30-
31-
if pkg_count > 0:
32-
rec = f"Install {pkg_count} updates (+{100-score} pts)"
37+
score -= (pkg_count * 2)
38+
score -= (sec_count * 10)
3339

34-
except FileNotFoundError:
35-
# Skip on non-apt environments (100 pts)
36-
return CheckResult("Updates", "updates", 100, "SKIP", "apt not found", weight=0.30)
3740
except Exception:
38-
pass # Ignore errors
41+
pass
3942

4043
status = "OK"
41-
if score < 60: status = "CRITICAL"
42-
elif score < 100: status = "WARNING"
44+
if score < 50: status = "CRITICAL"
45+
elif score < 90: status = "WARNING"
4346

44-
details = f"{pkg_count} pending"
45-
if sec_count > 0:
46-
details += f" ({sec_count} security)"
47+
details = f"{pkg_count} packages, {sec_count} security updates pending"
48+
if pkg_count == 0 and sec_count == 0:
49+
details = "System up to date"
4750

4851
return CheckResult(
4952
name="System Updates",
5053
category="updates",
5154
score=max(0, score),
5255
status=status,
5356
details=details,
54-
recommendation=rec,
55-
weight=0.30 # 30%
57+
recommendation="Run 'apt upgrade'" if score < 100 else None,
58+
weight=0.25
5659
)

0 commit comments

Comments
 (0)