Refactor visualize.py to use jinja2
This commit is contained in:
		
							parent
							
								
									73a1b21cad
								
							
						
					
					
						commit
						20bb2c8fd7
					
				
					 3 changed files with 114 additions and 73 deletions
				
			
		|  | @ -6,5 +6,6 @@ mkShell { | ||||||
| 		d2 | 		d2 | ||||||
| 		dnscontrol | 		dnscontrol | ||||||
| 		opentofu | 		opentofu | ||||||
|  | 		python3Packages.jinja2 | ||||||
| 	]; | 	]; | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										77
									
								
								templates/infrastructure.d2.j2
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								templates/infrastructure.d2.j2
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,77 @@ | ||||||
|  | vars: { | ||||||
|  |   d2-config: { | ||||||
|  |     layout-engine: elk | ||||||
|  |     theme-id: 101 | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | external: { | ||||||
|  |     scaleway: { | ||||||
|  |         s3 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     restic: { | ||||||
|  |         icon: https://cdn.jsdelivr.net/gh/selfhst/icons/webp/restic.webp | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | {% for host in hosts %} | ||||||
|  | {{ host.key }}: { | ||||||
|  | } | ||||||
|  | {% endfor %}{# host #} | ||||||
|  | 
 | ||||||
|  | {% for svc in svcs %} | ||||||
|  | {{ svc.key }}: { | ||||||
|  |     label: {{ svc.label }} | ||||||
|  |     label.near: top-left | ||||||
|  |     icon: {{ svc.icon }} | ||||||
|  |     icon.near: top-right | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | {% for backup in svc.backup or [] %} | ||||||
|  | {{ svc.key }} -> external.restic.{{ svc.host }}: backup.name { | ||||||
|  |     style: { | ||||||
|  |         stroke: "#0f0" | ||||||
|  |         stroke-dash: 3 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | {% endfor %}{# backup #} | ||||||
|  | 
 | ||||||
|  | {% if svc.monitoring %} | ||||||
|  | {{ monitoring_key }} -> {{ svc.key }}: { | ||||||
|  |     style.stroke: "#1E9025" | ||||||
|  | } | ||||||
|  | {% endif %} | ||||||
|  | 
 | ||||||
|  | {% if svc.database %} | ||||||
|  | {{ svc.key }} -> {{ db_key }}: { | ||||||
|  |     style.stroke: "#336791" | ||||||
|  | } | ||||||
|  | {{ db_key }}.{{ svc.name }} | ||||||
|  | {% endif %} | ||||||
|  | 
 | ||||||
|  | {% if svc.auth %} | ||||||
|  | {{ svc.key }} -> {{ auth_key }}: { | ||||||
|  |     style.stroke: "#FD4B2D" | ||||||
|  | } | ||||||
|  | {{ auth_key }}.{{ svc.name }} | ||||||
|  | {% endif %} | ||||||
|  | 
 | ||||||
|  | {% if svc.s3 %} | ||||||
|  | {{ svc.key }} -> external.scaleway.s3: { | ||||||
|  |     style: { | ||||||
|  |         stroke: "#110B1E" | ||||||
|  |         stroke-dash: 3 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | external.scaleway.s3.{{ svc.name }} | ||||||
|  | {% endif %} | ||||||
|  | 
 | ||||||
|  | {% endfor %}{# svc #} | ||||||
|  | 
 | ||||||
|  | {% for svc in grid_svcs %} | ||||||
|  | {{ svc }}: { | ||||||
|  |     grid-columns: 3 | ||||||
|  |     grid-gap: 0 | ||||||
|  | } | ||||||
|  | {% endfor %} | ||||||
							
								
								
									
										107
									
								
								visualize.py
									
										
									
									
									
								
							
							
						
						
									
										107
									
								
								visualize.py
									
										
									
									
									
								
							|  | @ -3,6 +3,8 @@ | ||||||
| import json | import json | ||||||
| import sys | import sys | ||||||
| 
 | 
 | ||||||
|  | import jinja2 | ||||||
|  | 
 | ||||||
| icon_overrides = { | icon_overrides = { | ||||||
|     "acme_dns": "lets-encrypt", |     "acme_dns": "lets-encrypt", | ||||||
|     "extra_services": None, |     "extra_services": None, | ||||||
|  | @ -24,41 +26,6 @@ icon_format = { | ||||||
|     "tiny-tiny-rss": "webp", |     "tiny-tiny-rss": "webp", | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| template_host = """ |  | ||||||
| 'serguzim.net'.{host}: {{ |  | ||||||
|     label: {host} |  | ||||||
| }} |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| template_service = """ |  | ||||||
| {key}: {{ |  | ||||||
|     label: {label} |  | ||||||
|     label.near: top-left |  | ||||||
|     icon: {icon} |  | ||||||
|     icon.near: top-right |  | ||||||
| }} |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| default_d2 = """ |  | ||||||
| vars: { |  | ||||||
|   d2-config: { |  | ||||||
|     layout-engine: elk |  | ||||||
|     # Terminal theme code |  | ||||||
|     theme-id: 101 |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| external: { |  | ||||||
|     scaleway: { |  | ||||||
|         s3 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     restic: { |  | ||||||
|         icon: https://cdn.jsdelivr.net/gh/selfhst/icons/webp/restic.webp |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| """ |  | ||||||
| 
 |  | ||||||
| def get_icon(svc): | def get_icon(svc): | ||||||
|     svc = icon_overrides.get(svc, svc) or 'docker' |     svc = icon_overrides.get(svc, svc) or 'docker' | ||||||
|     fmt = icon_format.get(svc, 'svg') |     fmt = icon_format.get(svc, 'svg') | ||||||
|  | @ -66,6 +33,9 @@ def get_icon(svc): | ||||||
| 
 | 
 | ||||||
| def service_key(svc, data): | def service_key(svc, data): | ||||||
|     return f"'serguzim.net'.{data['host']}.{svc}" |     return f"'serguzim.net'.{data['host']}.{svc}" | ||||||
|  | def host_key(host): | ||||||
|  |     return f"'serguzim.net'.{host}" | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| def service_key_find(svc_name, services): | def service_key_find(svc_name, services): | ||||||
|     for svc, data in services.items(): |     for svc, data in services.items(): | ||||||
|  | @ -75,8 +45,11 @@ def service_key_find(svc_name, services): | ||||||
| 
 | 
 | ||||||
| def parse_hosts(hosts): | def parse_hosts(hosts): | ||||||
|     result = [] |     result = [] | ||||||
|     for host in hosts.keys(): |     for host, data in hosts.items(): | ||||||
|         result.append(template_host.format(host=host)) |         result.append({ | ||||||
|  |             'key': host_key(host), | ||||||
|  |             'name': host, | ||||||
|  |         }) | ||||||
|     return result |     return result | ||||||
| 
 | 
 | ||||||
| def parse_services(services): | def parse_services(services): | ||||||
|  | @ -85,42 +58,23 @@ def parse_services(services): | ||||||
|     postgresql_key = service_key_find("postgresql", services) |     postgresql_key = service_key_find("postgresql", services) | ||||||
|     authentik_key = service_key_find("authentik", services) |     authentik_key = service_key_find("authentik", services) | ||||||
| 
 | 
 | ||||||
|     result.append(f"{postgresql_key}.grid-columns: 3") |  | ||||||
|     result.append(f"{postgresql_key}.grid-gap: 0") |  | ||||||
|     result.append(f"{authentik_key}.grid-columns: 3") |  | ||||||
|     result.append(f"{authentik_key}.grid-gap: 0") |  | ||||||
| 
 |  | ||||||
|     for svc, data in services.items(): |     for svc, data in services.items(): | ||||||
|         svc_key = service_key(svc, data) |         svc_key = service_key(svc, data) | ||||||
| 
 | 
 | ||||||
|         domains = [] |         domains = [] | ||||||
|         if data.get("dns"): |         for dns in data.get("dns") or []: | ||||||
|             domains = [] |             domain = "" | ||||||
|             for dns in data["dns"]: |             if dns.get("target") != "@": | ||||||
|                 domain = "" |                 domain += f"{dns["target"]}." | ||||||
|                 if dns.get("target") != "@": |             domain += dns['domain'] | ||||||
|                     domain += f"{dns["target"]}." |             domains.append(f"- {domain}") | ||||||
|                 domain += dns['domain'] |  | ||||||
|                 domains.append(f"- {domain}") |  | ||||||
| 
 | 
 | ||||||
|         result.append(template_service.format( |         data['key'] = svc_key | ||||||
|             key=svc_key, |         data['label'] = "\\n".join([svc] + domains) | ||||||
|             label="\\n".join([svc] + domains), |         data['icon'] = get_icon(svc) | ||||||
|             icon=get_icon(svc) |  | ||||||
|         )) |  | ||||||
| 
 | 
 | ||||||
|         for backup in data.get("backup") or []: |         result.append(data) | ||||||
|             result.append(f'({svc_key} -> external.restic.{data['host']}).style.stroke: "#0f0"') |  | ||||||
| 
 | 
 | ||||||
|         if data.get("database"): |  | ||||||
|             result.append(f"({svc_key} -> {postgresql_key}).style.stroke: '#00f'") |  | ||||||
|             result.append(f"{postgresql_key}.{svc}") |  | ||||||
|         if data.get("auth"): |  | ||||||
|             result.append(f"({svc_key} -> {authentik_key}).style.stroke: '#FD4B2D'") |  | ||||||
|             result.append(f"{authentik_key}.{svc}") |  | ||||||
|         if data.get("s3"): |  | ||||||
|             result.append(f"({svc_key} -> external.scaleway.s3).style.stroke: '#bbb'") |  | ||||||
|             result.append(f"external.scaleway.s3.{svc}") |  | ||||||
|     return result |     return result | ||||||
| 
 | 
 | ||||||
| if __name__ == '__main__': | if __name__ == '__main__': | ||||||
|  | @ -129,10 +83,19 @@ if __name__ == '__main__': | ||||||
| 
 | 
 | ||||||
|     data = json.loads(sys.stdin.read()) |     data = json.loads(sys.stdin.read()) | ||||||
| 
 | 
 | ||||||
|     hosts = parse_hosts(data["hosts"]) |     db_key = service_key_find("postgresql", data["services"]) | ||||||
|     services = parse_services(data["services"]) |     auth_key = service_key_find("authentik", data["services"]) | ||||||
|  |     monitoring_key = service_key_find("gatus", data["services"]) | ||||||
| 
 | 
 | ||||||
|     print("\n".join( |     jinja_loader = jinja2.FileSystemLoader(searchpath="./templates") | ||||||
|         [default_d2] |     jinja_env = jinja2.Environment(loader=jinja_loader) | ||||||
|             + hosts |     template = jinja_env.get_template("infrastructure.d2.j2") | ||||||
|             + services)) |     text = template.render( | ||||||
|  |         grid_svcs=[db_key, auth_key], | ||||||
|  |         svcs=parse_services(data["services"]), | ||||||
|  |         hosts=parse_hosts(data["hosts"]), | ||||||
|  |         db_key=db_key, | ||||||
|  |         auth_key=auth_key, | ||||||
|  |         monitoring_key=monitoring_key, | ||||||
|  |     ) | ||||||
|  |     print(text) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue