Add visualization script
This commit is contained in:
		
							parent
							
								
									13b69d5d4b
								
							
						
					
					
						commit
						dc398ddb6e
					
				
					 4 changed files with 137 additions and 0 deletions
				
			
		
							
								
								
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -10,3 +10,5 @@ secrets.auto.tfvars | ||||||
| inventory/group_vars/all/serguzim.net.yml | inventory/group_vars/all/serguzim.net.yml | ||||||
| inventory/group_vars/all/opentofu.yml | inventory/group_vars/all/opentofu.yml | ||||||
| inventory/group_vars/all/all_services.yml | inventory/group_vars/all/all_services.yml | ||||||
|  | 
 | ||||||
|  | infrastructure.svg | ||||||
|  |  | ||||||
							
								
								
									
										7
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										7
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -52,3 +52,10 @@ all: | ||||||
| 	$(MAKE) dns | 	$(MAKE) dns | ||||||
| 	@printf "\n=====\n\n" | 	@printf "\n=====\n\n" | ||||||
| 	ansible-playbook ./playbooks/serguzim.net.yml -t $(TAGS) | 	ansible-playbook ./playbooks/serguzim.net.yml -t $(TAGS) | ||||||
|  | 
 | ||||||
|  | visualize: | ||||||
|  | 	tofu output --json \
 | ||||||
|  | 		| jq 'with_entries(.value |= .value)' \
 | ||||||
|  | 		| ./visualize.py \
 | ||||||
|  | 		| d2 - infrastructure.svg | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ mkShell { | ||||||
| 	nativeBuildInputs = [ | 	nativeBuildInputs = [ | ||||||
| 		ansible | 		ansible | ||||||
| 		ansible-lint | 		ansible-lint | ||||||
|  | 		d2 | ||||||
| 		dnscontrol | 		dnscontrol | ||||||
| 		opentofu | 		opentofu | ||||||
| 	]; | 	]; | ||||||
|  |  | ||||||
							
								
								
									
										127
									
								
								visualize.py
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										127
									
								
								visualize.py
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,127 @@ | ||||||
|  | #!/usr/bin/env python | ||||||
|  | 
 | ||||||
|  | import json | ||||||
|  | import sys | ||||||
|  | 
 | ||||||
|  | icon_overrides = { | ||||||
|  |     "acme_dns": "lets-encrypt", | ||||||
|  |     "extra_services": None, | ||||||
|  |     "faas": None, | ||||||
|  |     "forgejo_runner": "forgejo", | ||||||
|  |     "healthcheck": "healthchecks", | ||||||
|  |     "mailcowdockerized": "mailcow", | ||||||
|  |     "reitanlage_oranienburg": "grav", | ||||||
|  |     "tandoor": "tandoor-recipes", | ||||||
|  |     "teamspeak_fallback": None, | ||||||
|  |     "tinytinyrss": "tiny-tiny-rss", | ||||||
|  |     "wiki_js": "wiki-js", | ||||||
|  |     "woodpecker": None, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template_host = """ | ||||||
|  | 'serguzim.net'.{host}: {{ | ||||||
|  |     label: {host} | ||||||
|  | }} | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | template_service = """ | ||||||
|  | {key}: {{ | ||||||
|  |     label: {label} | ||||||
|  |     label.near: top-left | ||||||
|  |     icon: https://cdn.jsdelivr.net/gh/selfhst/icons/webp/{icon}.webp | ||||||
|  |     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 service_key(svc, data): | ||||||
|  |     return f"'serguzim.net'.{data['host']}.{svc}" | ||||||
|  | 
 | ||||||
|  | def service_key_find(svc_name, services): | ||||||
|  |     for svc, data in services.items(): | ||||||
|  |         if svc == svc_name: | ||||||
|  |             return service_key(svc, data) | ||||||
|  |     return None | ||||||
|  | 
 | ||||||
|  | def parse_hosts(hosts): | ||||||
|  |     result = [] | ||||||
|  |     for host in hosts.keys(): | ||||||
|  |         result.append(template_host.format(host=host)) | ||||||
|  |     return result | ||||||
|  | 
 | ||||||
|  | def parse_services(services): | ||||||
|  |     result = [] | ||||||
|  | 
 | ||||||
|  |     postgresql_key = service_key_find("postgresql", 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(): | ||||||
|  |         svc_key = service_key(svc, data) | ||||||
|  | 
 | ||||||
|  |         domains = [] | ||||||
|  |         if data.get("dns"): | ||||||
|  |             domains = [] | ||||||
|  |             for dns in data["dns"]: | ||||||
|  |                 domain = "" | ||||||
|  |                 if dns.get("target") != "@": | ||||||
|  |                     domain += f"{dns["target"]}." | ||||||
|  |                 domain += dns['domain'] | ||||||
|  |                 domains.append(f"- {domain}") | ||||||
|  | 
 | ||||||
|  |         result.append(template_service.format( | ||||||
|  |             key=svc_key, | ||||||
|  |             label="\\n".join([svc] + domains), | ||||||
|  |             icon=icon_overrides.get(svc, svc) or "docker", | ||||||
|  |         )) | ||||||
|  | 
 | ||||||
|  |         for backup in data.get("backup") or []: | ||||||
|  |             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 | ||||||
|  | 
 | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     hosts = [] | ||||||
|  |     services = [] | ||||||
|  | 
 | ||||||
|  |     data = json.loads(sys.stdin.read()) | ||||||
|  |      | ||||||
|  |     hosts = parse_hosts(data["hosts"]) | ||||||
|  |     services = parse_services(data["services"]) | ||||||
|  | 
 | ||||||
|  |     print("\n".join( | ||||||
|  |         [default_d2] | ||||||
|  |             + hosts | ||||||
|  |             + services)) | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue