check-msdefender 1.1.15__tar.gz → 1.1.17__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/PKG-INFO +1 -1
  2. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/__init__.py +1 -1
  3. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/core/defender.py +3 -3
  4. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/core/nagios.py +2 -1
  5. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/services/machines_service.py +3 -3
  6. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/services/products_service.py +10 -8
  7. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/pyproject.toml +1 -1
  8. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/LICENSE +0 -0
  9. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/README.md +0 -0
  10. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/__main__.py +0 -0
  11. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/check_msdefender.py +0 -0
  12. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/cli/__init__.py +0 -0
  13. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/cli/__main__.py +0 -0
  14. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/cli/commands/__init__.py +0 -0
  15. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/cli/commands/alerts.py +0 -0
  16. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/cli/commands/detail.py +0 -0
  17. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/cli/commands/lastseen.py +0 -0
  18. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/cli/commands/machines.py +0 -0
  19. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/cli/commands/onboarding.py +0 -0
  20. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/cli/commands/products.py +0 -0
  21. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/cli/commands/vulnerabilities.py +0 -0
  22. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/cli/decorators.py +0 -0
  23. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/cli/handlers.py +0 -0
  24. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/core/__init__.py +0 -0
  25. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/core/auth.py +0 -0
  26. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/core/config.py +0 -0
  27. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/core/exceptions.py +0 -0
  28. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/core/logging_config.py +0 -0
  29. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/services/__init__.py +0 -0
  30. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/services/alerts_service.py +0 -0
  31. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/services/detail_service.py +0 -0
  32. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/services/lastseen_service.py +0 -0
  33. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/services/models.py +0 -0
  34. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/services/onboarding_service.py +0 -0
  35. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/check_msdefender/services/vulnerabilities_service.py +0 -0
  36. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/__init__.py +0 -0
  37. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/fixtures/__init__.py +0 -0
  38. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/fixtures/alerts_data.json +0 -0
  39. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/fixtures/machine_data.json +0 -0
  40. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/fixtures/mock_defender_client.py +0 -0
  41. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/fixtures/test_alerts_service.py +0 -0
  42. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/fixtures/test_detail_service.py +0 -0
  43. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/fixtures/test_lastseen_service.py +0 -0
  44. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/fixtures/test_onboarding_service.py +0 -0
  45. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/fixtures/test_vulnerabilities_service.py +0 -0
  46. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/fixtures/vulnerability_data.json +0 -0
  47. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/integration/__init__.py +0 -0
  48. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/integration/test_cli_integration.py +0 -0
  49. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/integration/test_lastseen_integration.py +0 -0
  50. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/unit/__init__.py +0 -0
  51. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/unit/test_alerts_service.py +0 -0
  52. {check_msdefender-1.1.15 → check_msdefender-1.1.17}/tests/unit/test_detail_service.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: check-msdefender
3
- Version: 1.1.15
3
+ Version: 1.1.17
4
4
  Summary: A Nagios plugin for monitoring Microsoft Defender API endpoints
5
5
  Keywords: nagios,monitoring,microsoft,graph,api,azure
6
6
  Author-Email: ldvchosal <ldvchosal@github.com>
@@ -1,4 +1,4 @@
1
1
  """Check Microsoft Defender API endpoints and check values - Nagios plugin."""
2
- __version__ = "1.1.15"
2
+ __version__ = "1.1.17"
3
3
  __author__ = "ldvchosal"
4
4
  __email__ = "ldvchosa@github.com"
@@ -225,14 +225,14 @@ class DefenderClient:
225
225
 
226
226
  token = self._get_token()
227
227
 
228
- # Use the TVM API endpoint for products
229
- url = f"{self.base_url}/api/machines/SoftwareVulnerabilitiesByMachine"
228
+ # Use the TVM API endpoint for vulnerabilities by machine
229
+ url = f"{self.base_url}/api/vulnerabilities/machinesVulnerabilities"
230
230
  headers = {
231
231
  "Authorization": f"Bearer {token}",
232
232
  "Content-Type": DefenderClient.application_json,
233
233
  }
234
234
 
235
- params = {"pageIndex": "1", "pageSize": "50000"}
235
+ params = {"$top": "10000"}
236
236
 
237
237
  try:
238
238
  start_time = time.time()
@@ -1,4 +1,5 @@
1
1
  """Nagios plugin implementation."""
2
+ import traceback
2
3
 
3
4
  import nagiosplugin
4
5
  from typing import List, Optional, Union, Any
@@ -137,7 +138,7 @@ class NagiosPlugin:
137
138
  return int(e.code) if e.code is not None else 0
138
139
 
139
140
  except Exception as e:
140
- print(f"UNKNOWN: {str(e)}")
141
+ print(f"UNKNOWN: {str(e)}\n{traceback.format_exc()}")
141
142
  return 3
142
143
 
143
144
 
@@ -40,13 +40,13 @@ class MachinesService:
40
40
 
41
41
  # Liat machines
42
42
  # Define the sort order
43
- status_priority = {"Onboarded": 1, "InsufficientInfo": 2, "Unsupported": 3}
43
+ status_priority = {"Onboarded": 1, "InsufficientInfo": 2, "Unsupported": 3, "CanBeOnboarded": 4}
44
44
 
45
- # Sort by priority
45
+ # Sort by priority (unknown statuses get priority 99)
46
46
  sorted_machines = sorted(
47
47
  machines,
48
48
  key=lambda x: (
49
- status_priority[x["onboardingStatus"] or ""],
49
+ status_priority.get(x["onboardingStatus"] or "", 99),
50
50
  x["computerDnsName"] or "",
51
51
  ),
52
52
  )
@@ -54,7 +54,7 @@ class ProductsService:
54
54
  products_data = self.defender.get_products()
55
55
  all_products = products_data.get("value", [])
56
56
  products = [
57
- product for product in all_products if product.get("deviceId") == target_machine_id
57
+ product for product in all_products if product.get("machineId") == target_machine_id
58
58
  ]
59
59
 
60
60
  self.logger.info(f"Found {len(products)} vulnerabilities for machine {target_dns_name}")
@@ -62,14 +62,14 @@ class ProductsService:
62
62
  # Group vulnerabilities by software
63
63
  software_vulnerabilities = {}
64
64
  for vulnerability in products:
65
- software_name = vulnerability.get("softwareName", "Unknown")
66
- software_version = vulnerability.get("softwareVersion", "Unknown")
67
- software_vendor = vulnerability.get("softwareVendor", "Unknown")
65
+ software_name = vulnerability.get("productName", "Unknown")
66
+ software_version = vulnerability.get("productVersion", "Unknown")
67
+ software_vendor = vulnerability.get("productVendor", "Unknown")
68
68
  cve_id = vulnerability.get("cveId", "Unknown")
69
69
  cvss_score = vulnerability.get("cvssScore", 0)
70
70
  disk_paths = vulnerability.get("diskPaths", [])
71
71
  registry_paths = vulnerability.get("registryPaths", [])
72
- severity = vulnerability.get("vulnerabilitySeverityLevel", "Unknown")
72
+ severity = vulnerability.get("severity", "Unknown")
73
73
 
74
74
  software_key = f"{software_name}-{software_version}-{software_vendor}"
75
75
 
@@ -101,7 +101,8 @@ class ProductsService:
101
101
  low_count = 0
102
102
 
103
103
  for vulnerability in products:
104
- severity = vulnerability.get("vulnerabilitySeverityLevel", "Unknown").lower()
104
+ severityLevel = vulnerability.get("severity", "Unknown")
105
+ severity = (severityLevel or "Unknown").lower()
105
106
  if severity == "critical":
106
107
  critical_count += 1
107
108
  elif severity == "high":
@@ -133,15 +134,16 @@ class ProductsService:
133
134
  cve_list = ", ".join(unique_cves[:5]) # Show first 5 CVEs
134
135
  severities = ""
135
136
  # Count severities
136
- severity_counts = {"Critical": 0, "High": 0, "Medium": 0, "Low": 0}
137
+ severity_counts = {"Critical": 0, "High": 0, "Medium": 0, "Low": 0, "Unknown": 0}
137
138
  for sev in software["severities"]:
139
+ sev = (sev or "Unknown")
138
140
  severity_counts[sev] += 1
139
141
  severities = ", ".join(
140
142
  f"{key}: {value}" for key, value in severity_counts.items() if value > 0
141
143
  )
142
144
 
143
145
  for cve in software["cves"]:
144
- severity = cve["severity"].lower()
146
+ severity = (cve["severity"] or "Unknown").lower()
145
147
  if severity == "critical":
146
148
  score += 100
147
149
  elif severity == "high":
@@ -39,7 +39,7 @@ dependencies = [
39
39
  "azure-identity>=1.12.0",
40
40
  "click>=8.0,<9.0",
41
41
  ]
42
- version = "1.1.15"
42
+ version = "1.1.17"
43
43
 
44
44
  [project.license]
45
45
  text = "MIT"