226 lines
8.2 KiB
Python
226 lines
8.2 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Script for generating Wiki page with applications list from Terraform outputs
|
|
"""
|
|
|
|
import json
|
|
import sys
|
|
import os
|
|
from datetime import datetime
|
|
|
|
def generate_markdown_table(apps_data):
|
|
"""Generates Markdown table for applications"""
|
|
|
|
# Combine all applications
|
|
all_apps = []
|
|
|
|
if 'proxy_apps' in apps_data:
|
|
for key, app in apps_data['proxy_apps'].items():
|
|
all_apps.append({
|
|
'key': key,
|
|
'name': app['name'],
|
|
'type': app['type'],
|
|
'url': app['url'],
|
|
'internal_url': app.get('internal_url', '-'),
|
|
'group': app['group'],
|
|
'description': app['description'],
|
|
'icon': app['icon'],
|
|
'slug': app['slug']
|
|
})
|
|
|
|
if 'oauth_apps' in apps_data:
|
|
for key, app in apps_data['oauth_apps'].items():
|
|
all_apps.append({
|
|
'key': key,
|
|
'name': app['name'],
|
|
'type': app['type'],
|
|
'url': app['url'],
|
|
'internal_url': '-', # OAuth apps don't have internal URLs
|
|
'group': app['group'],
|
|
'description': app['description'],
|
|
'icon': app['icon'],
|
|
'slug': app['slug']
|
|
})
|
|
|
|
# Sort by groups, then by name
|
|
all_apps.sort(key=lambda x: (x['group'], x['name']))
|
|
|
|
# Generate Markdown
|
|
markdown = []
|
|
markdown.append("# Authentik Applications")
|
|
markdown.append("")
|
|
markdown.append(f"*Automatically generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S UTC')}*")
|
|
markdown.append("")
|
|
markdown.append("## All Applications")
|
|
markdown.append("")
|
|
|
|
# Table
|
|
markdown.append("| Icon | Name | Type | External URL | Internal URL | Group | Description |")
|
|
markdown.append("|:----:|------|------|--------------|--------------|-------|-------------|")
|
|
|
|
for app in all_apps:
|
|
# Icon with size constraint
|
|
if app['icon']:
|
|
icon = f'<img src="{app["icon"]}" width="32" height="32" alt="{app["name"]}">'
|
|
else:
|
|
icon = "📱"
|
|
|
|
# External URL link
|
|
external_link = f"[🔗 {app['url'].replace('https://', '').replace('http://', '')}]({app['url']})" if app.get('url') else "-"
|
|
|
|
# Internal URL (only for proxy apps)
|
|
internal_url = app.get('internal_url', '-')
|
|
if internal_url != '-':
|
|
# Show full internal URL without shortening
|
|
internal_url = f"`{internal_url}`"
|
|
|
|
description = app['description'] if app['description'] else "-"
|
|
|
|
markdown.append(f"| {icon} | **{app['name']}** | {app['type']} | {external_link} | {internal_url} | {app['group']} | {description} |")
|
|
|
|
markdown.append("")
|
|
|
|
# Statistics
|
|
proxy_count = len(apps_data.get('proxy_apps', {}))
|
|
oauth_count = len(apps_data.get('oauth_apps', {}))
|
|
total_count = proxy_count + oauth_count
|
|
|
|
markdown.append("## Statistics")
|
|
markdown.append("")
|
|
markdown.append(f"- **Total applications**: {total_count}")
|
|
markdown.append(f"- **Proxy applications**: {proxy_count}")
|
|
markdown.append(f"- **OAuth2/OpenID applications**: {oauth_count}")
|
|
markdown.append("")
|
|
|
|
# Grouping by types
|
|
groups = {}
|
|
for app in all_apps:
|
|
group = app['group']
|
|
if group not in groups:
|
|
groups[group] = {'proxy': 0, 'oauth': 0}
|
|
if app['type'] == 'Proxy':
|
|
groups[group]['proxy'] += 1
|
|
else:
|
|
groups[group]['oauth'] += 1
|
|
|
|
markdown.append("## Applications by Groups")
|
|
markdown.append("")
|
|
for group, counts in sorted(groups.items()):
|
|
total = counts['proxy'] + counts['oauth']
|
|
markdown.append(f"- **{group}**: {total} applications (Proxy: {counts['proxy']}, OAuth: {counts['oauth']})")
|
|
|
|
markdown.append("")
|
|
markdown.append("---")
|
|
markdown.append("*This page is automatically generated via Terraform CI/CD*")
|
|
|
|
return "\n".join(markdown)
|
|
|
|
def parse_terraform_output(output_data):
|
|
"""Parse Terraform output JSON structure"""
|
|
# Check if this is a full terraform output (with value, type, sensitive fields)
|
|
if isinstance(output_data, dict) and 'applications_for_wiki' in output_data:
|
|
# This is full terraform output format
|
|
app_output = output_data.get('applications_for_wiki', {})
|
|
if isinstance(app_output, dict) and 'value' in app_output:
|
|
return app_output['value']
|
|
else:
|
|
return app_output
|
|
else:
|
|
# This is already the value extracted
|
|
return output_data
|
|
|
|
def main():
|
|
if len(sys.argv) < 2:
|
|
print("Usage: python3 generate-apps-wiki.py <terraform-output-json> [--debug]")
|
|
sys.exit(1)
|
|
|
|
output_file = sys.argv[1]
|
|
debug = "--debug" in sys.argv
|
|
|
|
try:
|
|
# Check if file exists and has content
|
|
if not os.path.exists(output_file):
|
|
print(f"ERROR: File {output_file} not found")
|
|
sys.exit(1)
|
|
|
|
file_size = os.path.getsize(output_file)
|
|
if file_size == 0:
|
|
print(f"ERROR: File {output_file} is empty")
|
|
sys.exit(1)
|
|
|
|
print(f"📄 Reading Terraform output file: {output_file} ({file_size} bytes)")
|
|
|
|
# Read file content
|
|
with open(output_file, 'r') as f:
|
|
content = f.read()
|
|
|
|
if debug:
|
|
print(f"🔍 File content preview: {content[:200]}...")
|
|
|
|
# Clean content - remove command line if present
|
|
if content.startswith('[command]'):
|
|
print("⚠️ Detected command prefix, removing...")
|
|
lines = content.split('\n', 1)
|
|
if len(lines) > 1:
|
|
content = lines[1]
|
|
if debug:
|
|
print(f"🔍 Cleaned content preview: {content[:200]}...")
|
|
else:
|
|
print("ERROR: File contains only command line, no JSON data")
|
|
sys.exit(1)
|
|
|
|
# Parse JSON
|
|
try:
|
|
terraform_output = json.loads(content)
|
|
except json.JSONDecodeError as e:
|
|
print(f"ERROR: Invalid JSON in {output_file}: {e}")
|
|
print(f"Content starts with: {repr(content[:100])}")
|
|
# Try to find where JSON starts
|
|
json_start = content.find('{')
|
|
if json_start > 0:
|
|
print(f"Found JSON starting at position {json_start}, retrying...")
|
|
content = content[json_start:]
|
|
try:
|
|
terraform_output = json.loads(content)
|
|
except json.JSONDecodeError as e2:
|
|
print(f"ERROR: Still invalid JSON: {e2}")
|
|
sys.exit(1)
|
|
else:
|
|
sys.exit(1)
|
|
|
|
# Extract application data using helper function
|
|
apps_data = parse_terraform_output(terraform_output)
|
|
|
|
if not apps_data:
|
|
print("ERROR: No applications data found in Terraform output")
|
|
if debug:
|
|
print(f"Full output structure: {json.dumps(terraform_output, indent=2)[:500]}...")
|
|
sys.exit(1)
|
|
|
|
# Check if we have correct structure
|
|
if 'proxy_apps' not in apps_data and 'oauth_apps' not in apps_data:
|
|
print("ERROR: Expected 'proxy_apps' or 'oauth_apps' in output")
|
|
print(f"Available keys: {list(apps_data.keys())}")
|
|
if debug and apps_data:
|
|
print(f"Data structure: {json.dumps(apps_data, indent=2)[:500]}...")
|
|
sys.exit(1)
|
|
|
|
print(f"📊 Found {len(apps_data.get('proxy_apps', {}))} proxy apps, {len(apps_data.get('oauth_apps', {}))} oauth apps")
|
|
|
|
# Generate Markdown
|
|
markdown_content = generate_markdown_table(apps_data)
|
|
|
|
# Write result
|
|
wiki_file = "Applications.md"
|
|
with open(wiki_file, 'w', encoding='utf-8') as f:
|
|
f.write(markdown_content)
|
|
|
|
print(f"✅ Wiki page generated: {wiki_file}")
|
|
print(f"📊 Total applications: {len(apps_data.get('proxy_apps', {})) + len(apps_data.get('oauth_apps', {}))}")
|
|
|
|
except Exception as e:
|
|
print(f"ERROR: {e}")
|
|
sys.exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
main() |