Fix description template strings not rendering (missing f-string prefix)
All multi-line ASCII art blocks in _generate_ticket_description were
regular strings, not f-strings — so {hostname}, {'━' * box_width},
{cluster_health}, etc. were sent as literal template text instead of
rendered values. Added f prefix to all affected triple-quoted strings:
banner, executive_summary, DRIVE SPECIFICATIONS, DRIVE TIMELINE,
SMART STATUS, PARTITION, CEPH CLUSTER STATUS, CPU STATUS,
NETWORK STATUS, CONTAINER STORAGE.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+10
-10
@@ -1330,7 +1330,7 @@ class SystemHealthMonitor:
|
|||||||
# content lines: prefix + field_width + ┃ = 80
|
# content lines: prefix + field_width + ┃ = 80
|
||||||
box_width = 78
|
box_width = 78
|
||||||
|
|
||||||
banner = """
|
banner = f"""
|
||||||
┏{'━' * box_width}┓
|
┏{'━' * box_width}┓
|
||||||
┃{' HARDWARE MONITORING ALERT TICKET '.center(box_width)}┃
|
┃{' HARDWARE MONITORING ALERT TICKET '.center(box_width)}┃
|
||||||
┣{'━' * box_width}┫
|
┣{'━' * box_width}┫
|
||||||
@@ -1342,7 +1342,7 @@ class SystemHealthMonitor:
|
|||||||
issue_type = self._get_issue_type(issue)
|
issue_type = self._get_issue_type(issue)
|
||||||
impact_level = self._get_impact_level(issue)
|
impact_level = self._get_impact_level(issue)
|
||||||
|
|
||||||
executive_summary = """
|
executive_summary = f"""
|
||||||
┏━ EXECUTIVE SUMMARY {'━' * (box_width - 20)}┓
|
┏━ EXECUTIVE SUMMARY {'━' * (box_width - 20)}┓
|
||||||
┃ Issue Type │ {issue_type:<60}┃
|
┃ Issue Type │ {issue_type:<60}┃
|
||||||
┃ Impact Level │ {impact_level:<60}┃
|
┃ Impact Level │ {impact_level:<60}┃
|
||||||
@@ -1407,7 +1407,7 @@ class SystemHealthMonitor:
|
|||||||
type_safe = drive_details.get('type') or 'N/A'
|
type_safe = drive_details.get('type') or 'N/A'
|
||||||
firmware_safe = drive_details.get('firmware') or 'N/A'
|
firmware_safe = drive_details.get('firmware') or 'N/A'
|
||||||
|
|
||||||
description += """
|
description += f"""
|
||||||
┏━ DRIVE SPECIFICATIONS {'━' * (box_width - 23)}┓
|
┏━ DRIVE SPECIFICATIONS {'━' * (box_width - 23)}┓
|
||||||
┃ Device Path │ {device_safe:<61}┃
|
┃ Device Path │ {device_safe:<61}┃
|
||||||
┃ Model │ {model_safe:<61}┃
|
┃ Model │ {model_safe:<61}┃
|
||||||
@@ -1422,7 +1422,7 @@ class SystemHealthMonitor:
|
|||||||
last_test_safe = last_test_date or 'N/A'
|
last_test_safe = last_test_date or 'N/A'
|
||||||
age_safe = age or 'N/A'
|
age_safe = age or 'N/A'
|
||||||
|
|
||||||
description += """
|
description += f"""
|
||||||
┏━ DRIVE TIMELINE {'━' * (box_width - 17)}┓
|
┏━ DRIVE TIMELINE {'━' * (box_width - 17)}┓
|
||||||
┃ Power-On Hours │ {power_on_safe:<56}┃
|
┃ Power-On Hours │ {power_on_safe:<56}┃
|
||||||
┃ Last SMART Test │ {last_test_safe:<56}┃
|
┃ Last SMART Test │ {last_test_safe:<56}┃
|
||||||
@@ -1435,7 +1435,7 @@ class SystemHealthMonitor:
|
|||||||
temp_value = drive_info.get('temperature')
|
temp_value = drive_info.get('temperature')
|
||||||
temp_safe = f"{temp_value}°C" if temp_value is not None else 'N/A'
|
temp_safe = f"{temp_value}°C" if temp_value is not None else 'N/A'
|
||||||
|
|
||||||
description += """
|
description += f"""
|
||||||
┏━ SMART STATUS {'━' * (box_width - 15)}┓
|
┏━ SMART STATUS {'━' * (box_width - 15)}┓
|
||||||
┃ Status │ {smart_status_safe:<62}┃
|
┃ Status │ {smart_status_safe:<62}┃
|
||||||
┃ Temperature │ {temp_safe:<62}┃
|
┃ Temperature │ {temp_safe:<62}┃
|
||||||
@@ -1467,7 +1467,7 @@ class SystemHealthMonitor:
|
|||||||
# Truncate mountpoint if too long for header
|
# Truncate mountpoint if too long for header
|
||||||
mountpoint_display = mountpoint_safe[:50] if len(mountpoint_safe) > 50 else mountpoint_safe
|
mountpoint_display = mountpoint_safe[:50] if len(mountpoint_safe) > 50 else mountpoint_safe
|
||||||
|
|
||||||
description += """
|
description += f"""
|
||||||
┏━ PARTITION: {mountpoint_display} {'━' * (box_width - 14 - len(mountpoint_display))}┓
|
┏━ PARTITION: {mountpoint_display} {'━' * (box_width - 14 - len(mountpoint_display))}┓
|
||||||
┃ Filesystem │ {fstype_safe:<61}┃
|
┃ Filesystem │ {fstype_safe:<61}┃
|
||||||
┃ Usage Meter │ {usage_meter} {usage_pct_str:>10}┃
|
┃ Usage Meter │ {usage_meter} {usage_pct_str:>10}┃
|
||||||
@@ -1520,7 +1520,7 @@ class SystemHealthMonitor:
|
|||||||
cpu_status = cpu_health.get('status', 'N/A')
|
cpu_status = cpu_health.get('status', 'N/A')
|
||||||
cpu_usage_str = f"{cpu_usage}%" if isinstance(cpu_usage, (int, float)) else cpu_usage
|
cpu_usage_str = f"{cpu_usage}%" if isinstance(cpu_usage, (int, float)) else cpu_usage
|
||||||
|
|
||||||
description += """
|
description += f"""
|
||||||
┏━ CPU STATUS {'━' * (box_width - 13)}┓
|
┏━ CPU STATUS {'━' * (box_width - 13)}┓
|
||||||
┃ Usage │ {cpu_usage_str:<61}┃
|
┃ Usage │ {cpu_usage_str:<61}┃
|
||||||
┃ Threshold │ {str(cpu_threshold) + '%':<61}┃
|
┃ Threshold │ {str(cpu_threshold) + '%':<61}┃
|
||||||
@@ -1553,7 +1553,7 @@ class SystemHealthMonitor:
|
|||||||
if len(issues_str) > 61:
|
if len(issues_str) > 61:
|
||||||
issues_str = issues_str[:58] + '...'
|
issues_str = issues_str[:58] + '...'
|
||||||
|
|
||||||
description += """
|
description += f"""
|
||||||
┏━ NETWORK STATUS {'━' * (box_width - 17)}┓
|
┏━ NETWORK STATUS {'━' * (box_width - 17)}┓
|
||||||
┃ Management │ {mgmt_status:<61}┃
|
┃ Management │ {mgmt_status:<61}┃
|
||||||
┃ Ceph Network │ {ceph_status:<61}┃
|
┃ Ceph Network │ {ceph_status:<61}┃
|
||||||
@@ -1585,7 +1585,7 @@ class SystemHealthMonitor:
|
|||||||
usage_meter = '█' * blocks + '░' * (50 - blocks)
|
usage_meter = '█' * blocks + '░' * (50 - blocks)
|
||||||
usage_pct_str = f"{usage_pct:.1f}%"
|
usage_pct_str = f"{usage_pct:.1f}%"
|
||||||
|
|
||||||
description += """
|
description += f"""
|
||||||
┏━ CONTAINER STORAGE {'━' * (box_width - 20)}┓
|
┏━ CONTAINER STORAGE {'━' * (box_width - 20)}┓
|
||||||
┃ VMID │ {vmid:<61}┃
|
┃ VMID │ {vmid:<61}┃
|
||||||
┃ Mountpoint │ {mountpoint:<61}┃
|
┃ Mountpoint │ {mountpoint:<61}┃
|
||||||
@@ -1613,7 +1613,7 @@ class SystemHealthMonitor:
|
|||||||
osd_up = sum(1 for o in osd_list if o.get('status') == 'up')
|
osd_up = sum(1 for o in osd_list if o.get('status') == 'up')
|
||||||
osd_summary = f"{osd_up}/{osd_total} up" if osd_total > 0 else 'N/A'
|
osd_summary = f"{osd_up}/{osd_total} up" if osd_total > 0 else 'N/A'
|
||||||
|
|
||||||
description += """
|
description += f"""
|
||||||
┏━ CEPH CLUSTER STATUS {'━' * (box_width - 22)}┓
|
┏━ CEPH CLUSTER STATUS {'━' * (box_width - 22)}┓
|
||||||
┃ Health │ {cluster_health:<61}┃
|
┃ Health │ {cluster_health:<61}┃
|
||||||
┃ Usage │ {usage_pct_str:<61}┃
|
┃ Usage │ {usage_pct_str:<61}┃
|
||||||
|
|||||||
Reference in New Issue
Block a user