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

1#!/usr/bin/env python3 

2""" 

3Get JSM service request SLA information. 

4 

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""" 

10 

11import sys 

12import os 

13import argparse 

14import json 

15from pathlib import Path 

16from typing import Optional, Dict, Any, List 

17 

18sys.path.insert(0, str(Path(__file__).parent.parent.parent / 'shared' / 'scripts' / 'lib')) 

19 

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) 

27 

28 

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. 

33 

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 

38 

39 Returns: 

40 SLA data 

41 

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) 

50 

51 

52def format_sla_text(sla_data: Dict[str, Any], show_details: bool = True) -> str: 

53 """Format SLA data as text output.""" 

54 lines = [] 

55 

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("") 

63 

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)) 

70 

71 return '\n'.join(lines) 

72 

73 

74def _format_single_sla(sla: Dict[str, Any], show_details: bool = True) -> List[str]: 

75 """Format a single SLA metric.""" 

76 lines = [] 

77 

78 name = sla.get('name', 'Unknown SLA') 

79 emoji = get_sla_status_emoji(sla) 

80 status = get_sla_status_text(sla) 

81 

82 lines.append(f"{emoji} {name}: {status}") 

83 

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')) 

92 

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}") 

97 

98 if ongoing.get('paused'): 

99 lines.append(" Status: ⏸ Paused") 

100 

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')) 

108 

109 lines.append(f" Completed: {stop_time}") 

110 lines.append(f" Goal: {goal}") 

111 lines.append(f" Actual: {elapsed}") 

112 

113 return lines 

114 

115 

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) 

119 

120 

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 

130 

131 Get specific SLA: 

132 %(prog)s SD-123 --sla-id 1 

133 

134 JSON output: 

135 %(prog)s SD-123 --output json 

136 """ 

137 ) 

138 

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') 

147 

148 args = parser.parse_args() 

149 

150 try: 

151 sla_data = get_slas( 

152 issue_key=args.request_key, 

153 sla_id=args.sla_id, 

154 profile=args.profile 

155 ) 

156 

157 if args.output == 'json': 

158 print(format_sla_json(sla_data)) 

159 else: 

160 print(format_sla_text(sla_data)) 

161 

162 return 0 

163 

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 

173 

174 

175if __name__ == '__main__': 

176 sys.exit(main())