Coverage for scripts / create_service_desk.py: 0%

89 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-25 18:08 -0500

1#!/usr/bin/env python3 

2""" 

3Create a new JSM service desk (admin only). 

4 

5Usage: 

6 python create_service_desk.py --name "IT Service Desk" --key ITS 

7 python create_service_desk.py --name "IT Service Desk" --key ITS --template simplified-it-service-desk 

8 python create_service_desk.py --name "IT Service Desk" --key ITS --dry-run 

9 python create_service_desk.py --list-templates 

10""" 

11 

12import sys 

13import os 

14import argparse 

15import json 

16import re 

17from pathlib import Path 

18 

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

20 

21from config_manager import get_jira_client 

22from error_handler import print_error, JiraError 

23from formatters import format_json 

24 

25 

26# Common service desk templates 

27TEMPLATES = { 

28 'simplified-it-service-desk': 'com.atlassian.servicedesk:simplified-it-service-desk', 

29 'it-service-desk': 'com.atlassian.servicedesk:itil-v2-service-desk-no-queues', 

30 'internal-service-desk': 'com.atlassian.servicedesk:simplified-internal-service-desk', 

31 'external-service-desk': 'com.atlassian.servicedesk:simplified-external-service-desk', 

32 'general-service-desk': 'com.atlassian.servicedesk:simplified-general-service-desk', 

33 'hr-service-desk': 'com.atlassian.servicedesk:simplified-hr-service-desk', 

34 'facilities-service-desk': 'com.atlassian.servicedesk:simplified-facilities-service-desk', 

35 'legal-service-desk': 'com.atlassian.servicedesk:simplified-legal-service-desk' 

36} 

37 

38 

39def validate_project_key(key: str) -> bool: 

40 """ 

41 Validate project key format. 

42 

43 Args: 

44 key: Project key to validate 

45 

46 Returns: 

47 True if valid, False otherwise 

48 """ 

49 # Must be 2-10 uppercase letters, starting with a letter 

50 if not key: 

51 return False 

52 if len(key) < 2 or len(key) > 10: 

53 return False 

54 if not re.match(r'^[A-Z][A-Z0-9]*$', key): 

55 return False 

56 return True 

57 

58 

59def list_available_templates() -> None: 

60 """List available service desk templates.""" 

61 print("Available Service Desk Templates:") 

62 print() 

63 print(f"{'Template Key':<30} {'Full Template ID':<70}") 

64 print(f"{'────────────':<30} {'────────────────':<70}") 

65 

66 for key, template_id in TEMPLATES.items(): 

67 print(f"{key:<30} {template_id:<70}") 

68 

69 print() 

70 print("Usage: --template <template-key>") 

71 

72 

73def create_service_desk(name: str, key: str, project_template_key: str, profile: str = None) -> dict: 

74 """ 

75 Create a new service desk. 

76 

77 Args: 

78 name: Service desk name 

79 key: Project key 

80 project_template_key: Project template key 

81 profile: JIRA profile to use 

82 

83 Returns: 

84 Created service desk data 

85 """ 

86 client = get_jira_client(profile) 

87 service_desk = client.create_service_desk(name, key, project_template_key) 

88 client.close() 

89 

90 return service_desk 

91 

92 

93def format_create_preview(name: str, key: str, template: str) -> None: 

94 """ 

95 Show preview of service desk to be created. 

96 

97 Args: 

98 name: Service desk name 

99 key: Project key 

100 template: Template key 

101 """ 

102 print("DRY RUN - Preview of Service Desk Creation:") 

103 print() 

104 print(f"Name: {name}") 

105 print(f"Key: {key}") 

106 print(f"Template: {template}") 

107 print() 

108 print("This service desk would be created with the above configuration.") 

109 print("Remove --dry-run flag to create the service desk.") 

110 

111 

112def format_service_desk_created_text(service_desk: dict) -> None: 

113 """ 

114 Format created service desk as human-readable text. 

115 

116 Args: 

117 service_desk: Created service desk data 

118 """ 

119 print("Successfully Created Service Desk:") 

120 print() 

121 print(f"ID: {service_desk.get('id', '')}") 

122 print(f"Project ID: {service_desk.get('projectId', '')}") 

123 print(f"Project Key: {service_desk.get('projectKey', '')}") 

124 print(f"Project Name: {service_desk.get('projectName', '')}") 

125 print() 

126 print("Next steps:") 

127 print(f" - View details: python get_service_desk.py {service_desk.get('id', '')}") 

128 print(f" - List request types: python list_request_types.py {service_desk.get('id', '')}") 

129 

130 

131def format_service_desk_created_json(service_desk: dict) -> str: 

132 """ 

133 Format created service desk as JSON. 

134 

135 Args: 

136 service_desk: Created service desk data 

137 

138 Returns: 

139 JSON string 

140 """ 

141 return format_json(service_desk) 

142 

143 

144def main(): 

145 parser = argparse.ArgumentParser( 

146 description='Create a new JSM service desk (requires admin permissions)', 

147 epilog='Example: python create_service_desk.py --name "IT Service Desk" --key ITS' 

148 ) 

149 

150 parser.add_argument('--name', '-n', 

151 help='Service desk name') 

152 parser.add_argument('--key', '-k', 

153 help='Project key (2-10 uppercase letters)') 

154 parser.add_argument('--template', '-t', 

155 default='simplified-it-service-desk', 

156 help='Project template key (default: simplified-it-service-desk)') 

157 parser.add_argument('--list-templates', '-l', 

158 action='store_true', 

159 help='List available templates') 

160 parser.add_argument('--dry-run', '-d', 

161 action='store_true', 

162 help='Preview creation without actually creating') 

163 parser.add_argument('--output', '-o', 

164 choices=['text', 'json'], 

165 default='text', 

166 help='Output format (default: text)') 

167 parser.add_argument('--profile', 

168 help='JIRA profile to use (default: from config)') 

169 

170 args = parser.parse_args() 

171 

172 try: 

173 # List templates and exit 

174 if args.list_templates: 

175 list_available_templates() 

176 return 

177 

178 # Validate required arguments 

179 if not args.name or not args.key: 

180 parser.error("--name and --key are required (or use --list-templates)") 

181 

182 # Validate project key 

183 if not validate_project_key(args.key): 

184 raise JiraError( 

185 f"Invalid project key: {args.key}\n" 

186 "Project key must be 2-10 uppercase letters, starting with a letter." 

187 ) 

188 

189 # Get full template ID 

190 template_id = TEMPLATES.get(args.template, args.template) 

191 

192 # Dry run mode 

193 if args.dry_run: 

194 format_create_preview(args.name, args.key, template_id) 

195 return 

196 

197 # Create service desk 

198 service_desk = create_service_desk( 

199 args.name, 

200 args.key, 

201 template_id, 

202 profile=args.profile 

203 ) 

204 

205 # Output results 

206 if args.output == 'json': 

207 print(format_service_desk_created_json(service_desk)) 

208 else: 

209 format_service_desk_created_text(service_desk) 

210 

211 except JiraError as e: 

212 print_error(e) 

213 sys.exit(1) 

214 except Exception as e: 

215 print_error(e, debug=True) 

216 sys.exit(1) 

217 

218 

219if __name__ == '__main__': 

220 main()