Coverage for scripts / get_sla.py: 20%
83 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-25 18:08 -0500
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-25 18:08 -0500
1#!/usr/bin/env python3
2"""
3Get JSM service request SLA information.
5Usage:
6 python get_sla.py SD-123
7 python get_sla.py SD-123 --sla-id 1
8 python get_sla.py SD-123 --output json
9"""
11import sys
12import os
13import argparse
14import json
15from pathlib import Path
16from typing import Optional, Dict, Any, List
18sys.path.insert(0, str(Path(__file__).parent.parent.parent / 'shared' / 'scripts' / 'lib'))
20from config_manager import get_jira_client
21from error_handler import print_error, JiraError, NotFoundError
22from formatters import print_success
23from jsm_utils import (
24 format_sla_time, format_duration, get_sla_status_emoji,
25 get_sla_status_text, is_sla_at_risk
26)
29def get_slas(issue_key: str, sla_id: Optional[str] = None,
30 profile: Optional[str] = None) -> Dict[str, Any]:
31 """
32 Get SLA information for a service request.
34 Args:
35 issue_key: Request key (e.g., 'SD-123')
36 sla_id: Specific SLA ID to retrieve (optional)
37 profile: JIRA profile to use
39 Returns:
40 SLA data
42 Raises:
43 NotFoundError: If request doesn't exist
44 """
45 with get_jira_client(profile) as client:
46 if sla_id:
47 return client.get_request_sla(issue_key, sla_id)
48 else:
49 return client.get_request_slas(issue_key)
52def format_sla_text(sla_data: Dict[str, Any], show_details: bool = True) -> str:
53 """Format SLA data as text output."""
54 lines = []
56 # Check if this is a single SLA or list of SLAs
57 if 'values' in sla_data:
58 # Multiple SLAs
59 slas = sla_data.get('values', [])
60 lines.append(f"\nSLAs: {len(slas)} metrics")
61 lines.append("=" * 80)
62 lines.append("")
64 for sla in slas:
65 lines.extend(_format_single_sla(sla, show_details))
66 lines.append("")
67 else:
68 # Single SLA
69 lines.extend(_format_single_sla(sla_data, show_details))
71 return '\n'.join(lines)
74def _format_single_sla(sla: Dict[str, Any], show_details: bool = True) -> List[str]:
75 """Format a single SLA metric."""
76 lines = []
78 name = sla.get('name', 'Unknown SLA')
79 emoji = get_sla_status_emoji(sla)
80 status = get_sla_status_text(sla)
82 lines.append(f"{emoji} {name}: {status}")
84 if show_details:
85 # Ongoing cycle
86 ongoing = sla.get('ongoingCycle')
87 if ongoing:
88 goal = format_duration(ongoing.get('goalDuration'))
89 elapsed = format_duration(ongoing.get('elapsedTime'))
90 remaining = format_duration(ongoing.get('remainingTime'))
91 breach_time = format_sla_time(ongoing.get('breachTime'))
93 lines.append(f" Goal: {goal}")
94 lines.append(f" Elapsed: {elapsed}")
95 lines.append(f" Remaining: {remaining}")
96 lines.append(f" Breach at: {breach_time}")
98 if ongoing.get('paused'):
99 lines.append(" Status: ⏸ Paused")
101 # Completed cycles
102 completed = sla.get('completedCycles', [])
103 if completed:
104 last = completed[-1]
105 goal = format_duration(last.get('goalDuration'))
106 elapsed = format_duration(last.get('elapsedTime'))
107 stop_time = format_sla_time(last.get('stopTime'))
109 lines.append(f" Completed: {stop_time}")
110 lines.append(f" Goal: {goal}")
111 lines.append(f" Actual: {elapsed}")
113 return lines
116def format_sla_json(sla_data: Dict[str, Any]) -> str:
117 """Format SLA data as JSON output."""
118 return json.dumps(sla_data, indent=2)
121def main():
122 """Main entry point."""
123 parser = argparse.ArgumentParser(
124 description='Get JSM service request SLA information',
125 formatter_class=argparse.RawDescriptionHelpFormatter,
126 epilog="""
127Examples:
128 Get all SLAs:
129 %(prog)s SD-123
131 Get specific SLA:
132 %(prog)s SD-123 --sla-id 1
134 JSON output:
135 %(prog)s SD-123 --output json
136 """
137 )
139 parser.add_argument('request_key',
140 help='Request key (e.g., SD-123)')
141 parser.add_argument('--sla-id',
142 help='Specific SLA metric ID')
143 parser.add_argument('--output', choices=['text', 'json'], default='text',
144 help='Output format (default: text)')
145 parser.add_argument('--profile',
146 help='JIRA profile to use from config')
148 args = parser.parse_args()
150 try:
151 sla_data = get_slas(
152 issue_key=args.request_key,
153 sla_id=args.sla_id,
154 profile=args.profile
155 )
157 if args.output == 'json':
158 print(format_sla_json(sla_data))
159 else:
160 print(format_sla_text(sla_data))
162 return 0
164 except NotFoundError as e:
165 print_error(f"Request not found: {e}")
166 return 1
167 except JiraError as e:
168 print_error(f"Failed to get SLA: {e}")
169 return 1
170 except Exception as e:
171 print_error(f"Unexpected error: {e}")
172 return 1
175if __name__ == '__main__':
176 sys.exit(main())