Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
generates a dot file from to Google Cloud Platform service dependencies
generates a dot file from the output of `google services list --available --format json`.
it only draws services that are referenced as a dependency.
import sys
from re import sub
import json
from typing import Dict, List
ServiceDictionary = Dict[str, "Service"]
all_services: ServiceDictionary = {}
class Service(object):
def __init__(self, s: dict):
super(Service, self).__init__()
self.config = s.get("config", {})
self.dependency_config = s.get("dependencyConfig", {})
self.service_accounts = s.get("serviceAccounts", [])
self.enabled = s.get("enabled")
def name(self):
return self.config.get("name")
def short_name(self):
return"", "")
def dot_id(self):
return sub(r"\W", "_", self.short_name)
def title(self):
return self.config.get("title",
def depends_on(self) -> List["Service"]:
global all_services
return list(
map(lambda n: all_services[n], self.dependency_config.get("dependsOn", []))
def directly_depends_on(self) -> List["Service"]:
global all_services
return list(
lambda n: all_services[n],
self.dependency_config.get("directlyDependsOn", []),
def read_all_services(f):
global all_services
all_services = { s for s in map(lambda s: Service(s), json.load(f))}
def add_missing_services():
global all_services
to_add = {}
for s in all_services.values():
for d in s.dependency_config.get("directlyDependsOn", []):
if d not in all_services:
to_add[d] = Service(
"config": {"name": d, "title": "(unlisted)"},
"dependencyConfig": {"directlyRequiredBy": []},
def generate_dot():
global all_services
sys.stdout.write("digraph google_services {\n")
for _, s in all_services.items():
if s.dependency_config.get("directlyRequiredBy"):
sys.stdout.write(f' {s.dot_id} [label="{}\\n{s.title}"];\n')
for _, s in all_services.items():
for d in s.directly_depends_on:
sys.stdout.write(f" {s.dot_id} -> {d.dot_id};\n")
def dot_id(s: str) -> str:
return sub(r"\W", "_", s.replace("", ""))
if __name__ == "__main__":
[[ $# -ne 1 ]] && echo "Usage: $(basename $0) service-name" >&2 && exit 1
# allow shorthand notation, eg: cloudfunctions
if [[ ! $SERVICE =~ .*\ ]]; then
# cache the available services for an hour (I bet they result is pretty static)
CACHE=${TMP:-/tmp}/gcloud-available-services-cache-$(date -u +%Y-%m-%d-%H)
if [[ ! -s $CACHE ]] ; then
rm -f ${TMP:-/tmp}/gcloud-available-services-cache-$(date -u +%Y-)*
gcloud services list --available --format json > $CACHE
jq --arg service "$SERVICE" \
'map(select( == $service)|
dependsOn: .dependencyConfig.dependsOn
)| .[]' $CACHE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment