(outputs-d2)= # Declarative Diagramming (D2) Output Module *d2* output module create a description of network topology in [D2 diagram scripting language](https://d2lang.com/tour/intro). You can use that description with [D2 commands](https://d2lang.com/tour/install) to create topology- or routing protocol diagrams. **Note:** The graph descriptions contain nodes and links, but no placement information. D2 is pretty good at figuring out how to draw the required graph, but it pays off to test out the [layout engines](https://d2lang.com/tour/layouts). Changing the [order of nodes or links](outputs-d2-link-node-attributes) might also unclutter the diagrams. ``` ```eval_rst .. contents:: Table of Contents :depth: 2 :local: :backlinks: none ``` ## Creating Graph Description File The *d2* output module is invoked with the **[netlab graph -e d2](netlab-graph)** command or by specifying the `-o d2` parameter in the **[netlab create](netlab-create)** command. It takes an optional destination file name (default: `graph.d2`). The `-t` parameter of the **netlab graph** command or a formatting modifier in the **netlab create** `-o` parameter can be used to specify the graph type: * **topology** (default) -- Includes point-to-point links, multi-access bridges, and stub subnets. When the network topology contains BGP information, the graph groups nodes into autonomous systems. Alternatively, you could set the **defaults.outputs.d2.groups** attribute to use topology **[groups](topo-groups)** to group graph nodes. * **bgp** -- Include autonomous systems, BGP routers, and color-coded BGP sessions. * **isis** -- Create a diagram of IS-IS routing, including areas, color-coded circuit types, and edge subnets (does not work with IS-IS running over VLANs) ```{tip} The `‑f` parameter of the **netlab graph** command or a formatting modifier of the **‌netlab create** `‑o` parameter can include [BGP formatting parameters](outputs-graph-bgp-parameters). For example, `netlab graph -t bgp -f vrf` draws VRF BGP sessions as dotted lines. ``` (outputs-d2-link-node-attributes)= ## Modifying Global, Link, and Node Graph Attributes You can set the graph title with **graph.title** or **defaults.graph.title** topology attribute. You can use the **d2** link and node attributes to change the style of individual nodes or links. The following attributes are built into _netlab_ (but see also [](outputs-d2-styles)): * **d2.color** -- line color (*stroke* in D2 lingo) * **d2.fill** -- fill color (*fill* in D2 lingo) * **d2.width** -- line width (*stroke-width* in D2 lingo) ```{tip} The generic link- and node attributes can also be specified as **graph._attribute_** (for example, **graph.color**) values to use the same settings for GraphViz and D2 graphs. ``` You can also use the **d2.format** node attribute to specify D2 shape [dimensions](https://d2lang.com/tour/dimensions/) or [position](https://d2lang.com/tour/positions/) and the **d2.format.style** node/link[^LFA] attribute to specify the [D2 style](https://d2lang.com/tour/style/) of a shape or a connection. For example, to draw a node as a rectangle 250 units wide and 70 units high, use: ``` nodes: spine: d2.format: width: 250 height: 70 shape: rectangle ``` To change the fill pattern of a node, use: ``` nodes: spine: d2.format: style.fill-pattern: grain ``` Likewise, to turn a link into a dashed line, use: ``` links: - interfaces: [ a,b ] d2.format.style.stroke-dash: 5 ``` [^LFA]: Link attributes are applied to links between nodes or to the node representing a multi-access subnet. (outputs-d2-layout)= ## Influencing the Graph Layout _netlab_ uses the node **graph.rank** attribute to sort nodes in link definitions to ensure the graph edges are always defined as going from nodes with a lower rank to nodes with a higher rank. The order of nodes in the graph edges influences the D2 layout engine. The default value of the **graph.rank** attribute is 100, allowing you to push some nodes (with rank below 100) toward the top of the graph and others (with rank above 100) toward the bottom. You can also use the **graph.rank** on links to influence how D2 draws multi-access links. Finally, the link/interface **graph.linkorder** attribute allows you to specify the node order in individual links. The default **graph.linkorder** value is 50 for interfaces and 100 for subnets (multi-access links), resulting in subnets being "below" nodes unless you change the link- or interface **graph.linkorder** value. (outputs-d2-graph-appearance)= ## Modifying Graph Appearance Graphing routines use **[default](topo-defaults)** topology settings to modify the node- or link parameters of the generated D2 file: * **outputs.d2.interface_labels** (default: False) -- Add IP addresses to links in **topology** graph. Results in a cluttered image. * **outputs.d2.groups** (default: None) -- use the specified list of groups (or all groups when set to *True*) to create graph clusters * **outputs.d2.node_address_label** (default: True) -- add node loopback IP addresses or IP addresses of the first interface (for hosts) to node labels. * **outputs.d2.as_clusters** (default: True) -- use BGP autonomous systems to cluster nodes in the topology graph. BGP AS clusters are always used in BGP graphs. (outputs-d2-topo-parameters)= These default settings modify how the topology graphs look: * **outputs.d2.topology.vlan** (default: False) -- draw VLAN links in a different color. Use wider lines for VLAN trunk links. (outputs-d2-bgp-parameters)= These default settings modify how the BGP graphs look: * **outputs.d2.bgp.all** (default: False) -- show all lab devices in the BGP graph. By default, the BGP graphs include only lab devices running BGP. * **outputs.d2.bgp.rr** (default: True) -- draw arrows on BGP sessions to indicate peer-to-peer versus reflector-client sessions * **outputs.d2.bgp.vrf** (default: False) -- draw VRF BGP sessions as dotted lines * **outputs.d2.bgp.af._af_** (default: all address families) -- when one or more **af** parameters (valid keys: **ipv4**, **ipv6**, **vpnv4**, **vpnv6**, **6pe**, **evpn**) are set to *True*, the graph is limited to BGP sessions of the specified address families. * **outputs.d2.bgp.novrf** (default: False) -- do not include VRF BGP sessions in the graph You can specify the above BGP parameters in the *graph format* CLI argument. ## Modifying Shape and Connection Attributes *d2* output module uses `graphite.icon` device attribute to select the node style defined in **defaults.outputs.d2.styles** settings: | graphite icon | D2 style | |---------------|-----------------| | router | oval shape | | switch | hexagonal shape | You can also style these objects: | Object | Description | |--------|-------------| | container | Autonomous system/group container formatting | | title | Graph title formatting | | node | Default device formatting | | edge | Link formatting | | lan | Multi-access subnet formatting | | stub | Stub network formatting | | ibgp | IBGP session formatting | | ebgp | IBGP session formatting | | localas_ibgp | Local-AS IBGP session formatting | | confed_ebgp | Confederation EBGP session formatting | | vrf | BGP VRF session formatting | | level-1 | IS-IS level-1-only link | | level-2 | IS-IS level-2-only link | | level-1-2 | IS-IS level-1-2 link | | vlan_access | VLAN access link | | vlan_trunk | VLAN trunk link | Each style definition is a dictionary of D2 shape/connection attributes and their values. To change the style of a D2 shape or connection, use the **style** dictionary within a style definition. For example, to change the color of the VRF BGP sessions to red, use: ``` defaults.outputs.d2.styles.vrf.style.color: red ``` You could specify D2 attributes in your [topology file](defaults-topology) (where you would have to prefix them with **defaults**), in [per-user topology defaults](defaults-user-file), or with [environment variables](defaults-env) (even [more details](../defaults.md)). You could also specify them with the `-s` parameter of the **[netlab create](netlab-create)** command, yet again prefixed with **defaults** ([more details](netlab-create-set)). To display the current system defaults, use the **‌netlab show defaults outputs.d2.styles** command. ```{warning} _netlab_ releases 25.07 and older specified D2 style attributes in the **‌defaults.outputs.d2** dictionary. The style attributes recognized by those releases are automatically migrated into the **‌defaults.outputs.d2.styles** dictionary. ``` (outputs-d2-styles)= ## Extending D2 Style Attributes You can define your own link/node style attributes: * Define the attribute within **defaults.outputs.d2.attributes** dictionary. For example, you might define **d2.background** node attribute (a string) to add background color to nodes[^AD]: ``` defaults.outputs.d2.attributes.node.background: str ``` * Define a mapping between your attribute and D2 style attribute within the **defaults.outputs.d2.style_map** dictionary. For example, your **d2.background** attribute maps into D2 **style.fill** attribute: ``` defaults.outputs.d2.style_map.background: fill ``` [^AD]: See [](dev-attribute-validation) and [](dev-valid-data-types) for more details. ## Sample Graphs The lab topologies used for platform integration testing contain numerous examples of graph attributes: * [Leaf-and-spine topology](https://github.com/ipspace/netlab/blob/master/tests/platform-integration/graph/topo.yml) used to create topology graphs and test node- and link attributes and custom formatting. * [EVPN topology](https://github.com/ipspace/netlab/blob/master/tests/platform-integration/graph/bgp.yml) used to create BGP graphs * [IS-IS topology](https://github.com/ipspace/netlab/blob/master/tests/platform-integration/graph/isis.yml) used to create IS-IS graphs and test node ranking You'll find [further graph-creation tips](https://blog.ipspace.net/tag/netlab/#graph) on the ipSpace.net blog.