Coverage for scripts / update_asset.py: 23%

48 statements  

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

1#!/usr/bin/env python3 

2""" 

3Update an existing asset/CMDB object. 

4 

5Updates asset attributes. 

6Requires JSM Premium license or Assets license. 

7 

8Usage: 

9 update_asset.py --id 10001 --attr "Status=Inactive" 

10 update_asset.py --id 10001 --attr "Status=Inactive" --attr "Location=DC-2" --dry-run 

11""" 

12 

13import argparse 

14import sys 

15import json 

16from pathlib import Path 

17 

18# Add shared lib to path 

19shared_lib_path = str(Path(__file__).parent.parent.parent.parent / 'shared' / 'scripts' / 'lib') 

20if shared_lib_path not in sys.path: 

21 sys.path.insert(0, shared_lib_path) 

22 

23from config_manager import get_jira_client 

24 

25 

26def update_asset(asset_id: int, attributes: dict, dry_run: bool = False): 

27 """ 

28 Update an existing asset. 

29 

30 Args: 

31 asset_id: Asset object ID 

32 attributes: Dict mapping attribute names to new values 

33 dry_run: If True, don't actually update 

34 

35 Returns: 

36 Updated asset object (or None if dry_run) 

37 """ 

38 with get_jira_client() as client: 

39 # Check license first 

40 if not client.has_assets_license(): 

41 print("ERROR: Assets/Insight not available. Requires JSM Premium license.", file=sys.stderr) 

42 sys.exit(1) 

43 

44 if dry_run: 

45 print("DRY RUN: Would update asset with:") 

46 print(f" Asset ID: {asset_id}") 

47 print(f" Attributes: {json.dumps(attributes, indent=4)}") 

48 return None 

49 

50 return client.update_asset(asset_id, attributes) 

51 

52 

53def parse_attributes(attr_list: list) -> dict: 

54 """Parse attribute list into dict.""" 

55 attributes = {} 

56 for attr_str in attr_list: 

57 if '=' not in attr_str: 

58 raise ValueError(f"Invalid attribute format: {attr_str}. Expected: name=value") 

59 name, value = attr_str.split('=', 1) 

60 attributes[name.strip()] = value.strip() 

61 return attributes 

62 

63 

64def main(): 

65 parser = argparse.ArgumentParser( 

66 description="Update existing asset/CMDB object", 

67 formatter_class=argparse.RawDescriptionHelpFormatter, 

68 epilog=__doc__ 

69 ) 

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

71 help='Asset object ID') 

72 parser.add_argument('--attr', action='append', required=True, 

73 help='Attribute in format name=value (can be used multiple times)') 

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

75 help='Preview changes without updating') 

76 parser.add_argument('--profile', help='JIRA profile to use') 

77 

78 args = parser.parse_args() 

79 

80 try: 

81 attributes = parse_attributes(args.attr) 

82 asset = update_asset(args.id, attributes, args.dry_run) 

83 

84 if not args.dry_run: 

85 print(f"✓ Asset updated successfully!") 

86 print(f"Asset ID: {asset.get('id')}") 

87 print(f"Asset Key: {asset.get('objectKey')}") 

88 

89 except SystemExit: 

90 raise 

91 except Exception as e: 

92 print(f"Error updating asset: {str(e)}", file=sys.stderr) 

93 sys.exit(1) 

94 

95 

96if __name__ == "__main__": 

97 main()