Coverage for scripts / list_assets.py: 22%
54 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"""
3List and search assets/CMDB objects with IQL filtering.
5Lists assets from Insight/Assets with optional IQL query filtering.
6Requires JSM Premium license or Assets license.
8Usage:
9 list_assets.py
10 list_assets.py --type Server
11 list_assets.py --iql 'Status="Active"'
12 list_assets.py --type Server --iql 'Status="Active"'
13 list_assets.py --output json
14"""
16import argparse
17import sys
18import json
19from pathlib import Path
21# Add shared lib to path
22shared_lib_path = str(Path(__file__).parent.parent.parent.parent / 'shared' / 'scripts' / 'lib')
23if shared_lib_path not in sys.path:
24 sys.path.insert(0, shared_lib_path)
26from config_manager import get_jira_client
29def list_assets(object_type: str = None, iql: str = None, max_results: int = 100):
30 """
31 List assets with optional filtering.
33 Args:
34 object_type: Optional object type name
35 iql: Optional IQL query string
36 max_results: Maximum results to return
38 Returns:
39 List of asset objects
40 """
41 with get_jira_client() as client:
42 # Check license first
43 if not client.has_assets_license():
44 print("ERROR: Assets/Insight not available. Requires JSM Premium license.", file=sys.stderr)
45 sys.exit(1)
47 return client.list_assets(object_type, iql, max_results)
50def format_text(assets: list) -> str:
51 """Format assets as human-readable text."""
52 if not assets:
53 return "No assets found matching criteria."
55 output = [f"Assets ({len(assets)} total):\n"]
57 for asset in assets:
58 output.append(f"Key: {asset.get('objectKey', 'N/A')}")
59 output.append(f"Label: {asset.get('label', 'N/A')}")
61 if 'objectType' in asset:
62 output.append(f"Type: {asset['objectType'].get('name', 'N/A')}")
64 if 'attributes' in asset:
65 for attr in asset['attributes'][:3]: # Show first 3 attributes
66 attr_name = attr.get('objectTypeAttribute', {}).get('name', 'Unknown')
67 values = attr.get('objectAttributeValues', [])
68 if values:
69 attr_value = values[0].get('value', 'N/A')
70 output.append(f" {attr_name}: {attr_value}")
72 output.append("")
74 return "\n".join(output)
77def format_json(assets: list) -> str:
78 """Format assets as JSON."""
79 return json.dumps(assets, indent=2)
82def main():
83 parser = argparse.ArgumentParser(
84 description="List assets/CMDB objects",
85 formatter_class=argparse.RawDescriptionHelpFormatter,
86 epilog=__doc__
87 )
88 parser.add_argument('--type', help='Object type name filter')
89 parser.add_argument('--iql', help='IQL query string for filtering')
90 parser.add_argument('--max-results', type=int, default=100,
91 help='Maximum results to return (default: 100)')
92 parser.add_argument('--output', choices=['text', 'json'], default='text',
93 help='Output format (default: text)')
94 parser.add_argument('--profile', help='JIRA profile to use')
96 args = parser.parse_args()
98 try:
99 assets = list_assets(args.type, args.iql, args.max_results)
101 if args.output == 'json':
102 print(format_json(assets))
103 else:
104 print(format_text(assets))
106 except SystemExit:
107 raise
108 except Exception as e:
109 print(f"Error listing assets: {str(e)}", file=sys.stderr)
110 sys.exit(1)
113if __name__ == "__main__":
114 main()