GraphBuilder.build(assets, edges) adds account_id to node attributes and relationship /
description to edge attributes; endpoints that are not assets become EXTERNAL nodes. The
graph keeps one edge per source and target: parallel SECURITY_GROUP_RULE, NACL_RULE and
INTERNET_EXPOSED edges with the same cidr and direction are merged (ports and protocols
become comma lists, descriptions are joined with "; "), and any other parallel edge replaces
the earlier one. Graph exports therefore have fewer edges than the map
(reference).
The ontology (cloudg/graph/ontology.py) creates OWL classes for every asset type
automatically and uses an edge's declared relationship first. On CONTAINS, ATTACHED_TO
and the typed edges (INVOKES, REFERENCES, PROTECTS and the rest) the declared relation
replaces inference; on SECURITY_GROUP_RULE, IAM_TRUST, IAM_POLICY_ATTACHMENT,
LOAD_BALANCER_TARGET, ROUTE, PEERING and INTERNET_EXPOSED edges the inferred relations
are added after it. Inferred containment relations check both endpoint types (a
VPC_CONTAINS_SUBNET needs a VPC or VNet and a subnet; anything that matches no specific
relation is plain CONTAINS), and port relations come from the parsed port ranges
(cloudg.graph.ports). New relationship values must therefore be
RelationType names; add a new name to ontology_rules.RelationType (and its group) before
using it.
docs/viewer.html reads inventory-graph.json: node type, account_id, is_external
and link type / relationship drive its colouring and filters.