#!/usr/bin/env python3 """ Extract all Azure role names from rbacLookup.bicep and generate Python code for _KNOWN_ENUMS in modules.py. Usage: python3 scripts/extract_roles_from_rbaclookup.py /path/to/rbacLookup.bicep """ import re import sys from pathlib import Path def extract_role_names(bicep_file: Path) -> list[str]: """Extract all role names from the rbacLookup.bicep var roles = {...} block.""" content = bicep_file.read_text() # Find the "var roles = {" block roles_match = re.search(r'@export\(\)\s*var\s+roles\s*=\s*\{(.+?)\n\}', content, re.DOTALL) if not roles_match: raise ValueError("Could not find 'var roles = {' block in Bicep file") roles_block = roles_match.group(1) # Extract all role names (keys before the colon) # Pattern: " ROLE_NAME: 'guid'" role_names = re.findall(r'^\s+([A-Z_]+):', roles_block, re.MULTILINE) return sorted(role_names) def generate_python_code(role_names: list[str]) -> str: """Generate Python code for _KNOWN_ENUMS["roles"].""" lines = ['_KNOWN_ENUMS = {'] lines.append(' "roles": [') for role in role_names: lines.append(f' "{role}",') lines.append(' ],') lines.append(' "roleDefinitionIds": [ # alias for roles') for role in role_names: lines.append(f' "{role}",') lines.append(' ],') lines.append('}') return '\n'.join(lines) if __name__ == "__main__": if len(sys.argv) < 2: print("Usage: extract_roles_from_rbaclookup.py /path/to/rbacLookup.bicep", file=sys.stderr) sys.exit(1) bicep_path = Path(sys.argv[1]) if not bicep_path.exists(): print(f"Error: File not found: {bicep_path}", file=sys.stderr) sys.exit(1) try: roles = extract_role_names(bicep_path) print(f"# Extracted {len(roles)} roles from {bicep_path.name}") print(f"# Generated: {Path(__file__).name}\n") print(generate_python_code(roles)) except Exception as e: print(f"Error: {e}", file=sys.stderr) sys.exit(1)