Coverage for scripts / remove_from_organization.py: 0%

46 statements  

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

1#!/usr/bin/env python3 

2""" 

3Remove users from a JSM organization. 

4 

5Usage: 

6 python remove_from_organization.py 12345 --account-id 5b10ac8d82e05b22cc7d4ef5 --yes 

7 python remove_from_organization.py 12345 --account-id "id1,id2" --yes 

8 python remove_from_organization.py 12345 --account-id id1 --dry-run 

9""" 

10 

11import sys 

12import os 

13import argparse 

14from pathlib import Path 

15 

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

17 

18from config_manager import get_jira_client 

19from error_handler import print_error, JiraError 

20from formatters import print_success 

21 

22 

23def parse_account_ids(account_id_string: str) -> list: 

24 """ 

25 Parse comma-separated account IDs. 

26 

27 Args: 

28 account_id_string: Comma-separated account IDs 

29 

30 Returns: 

31 List of account IDs 

32 """ 

33 return [id.strip() for id in account_id_string.split(',') if id.strip()] 

34 

35 

36def remove_users_from_organization_func(organization_id: int, account_ids: list, 

37 profile: str = None) -> None: 

38 """ 

39 Remove users from an organization. 

40 

41 Args: 

42 organization_id: Organization ID 

43 account_ids: List of user account IDs 

44 profile: JIRA profile to use 

45 """ 

46 with get_jira_client(profile) as client: 

47 client.remove_users_from_organization(organization_id, account_ids) 

48 

49 

50def main(): 

51 """Main entry point.""" 

52 parser = argparse.ArgumentParser( 

53 description='Remove users from a JSM organization', 

54 formatter_class=argparse.RawDescriptionHelpFormatter, 

55 epilog=""" 

56Examples: 

57 Remove single user (with confirmation skip): 

58 %(prog)s 12345 --account-id 5b10ac8d82e05b22cc7d4ef5 --yes 

59 

60 Remove multiple users: 

61 %(prog)s 12345 --account-id "id1,id2" --yes 

62 

63 Dry-run: 

64 %(prog)s 12345 --account-id id1 --dry-run 

65 """ 

66 ) 

67 

68 parser.add_argument('organization_id', type=int, 

69 help='Organization ID') 

70 parser.add_argument('--account-id', required=True, 

71 help='User account ID(s) (comma-separated)') 

72 parser.add_argument('--yes', '-y', action='store_true', 

73 help='Skip confirmation prompt') 

74 parser.add_argument('--dry-run', action='store_true', 

75 help='Show what would be removed without removing') 

76 parser.add_argument('--profile', 

77 help='JIRA profile to use from config') 

78 

79 args = parser.parse_args() 

80 

81 try: 

82 account_ids = parse_account_ids(args.account_id) 

83 

84 if not account_ids: 

85 print_error("Invalid or empty account IDs") 

86 return 1 

87 

88 if args.dry_run: 

89 print("DRY RUN MODE - No changes will be made\n") 

90 print(f"Would remove {len(account_ids)} user(s) from organization {args.organization_id}:") 

91 for account_id in account_ids: 

92 print(f" - {account_id}") 

93 return 0 

94 

95 if not args.yes: 

96 print_error("Confirmation required. Use --yes flag to confirm removal.") 

97 return 1 

98 

99 remove_users_from_organization_func( 

100 organization_id=args.organization_id, 

101 account_ids=account_ids, 

102 profile=args.profile 

103 ) 

104 

105 print_success(f"Successfully removed {len(account_ids)} user(s) from organization {args.organization_id}") 

106 

107 return 0 

108 

109 except JiraError as e: 

110 print_error(f"Failed to remove users from organization: {e}") 

111 return 1 

112 except Exception as e: 

113 print_error(f"Unexpected error: {e}") 

114 return 1 

115 

116 

117if __name__ == '__main__': 

118 sys.exit(main())