Skip to content

Commit f71b9f0

Browse files
committed
Update to v0.13.0
- Introduced unified node selection system. - Enhanced variable and bracket expansion. - Removed deprecated `source_path` and `sink_path` attributes.
1 parent f3ef090 commit f71b9f0

File tree

81 files changed

+7914
-2864
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+7914
-2864
lines changed
Lines changed: 348 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,348 @@
1+
---
2+
name: netgraph-dsl
3+
description: >
4+
NetGraph scenario DSL for defining network topologies, traffic demands, failure policies,
5+
and analysis workflows in YAML. Use when: creating or editing .yaml/.yml network scenarios,
6+
defining nodes/links/groups, writing adjacency rules, configuring selectors or blueprints,
7+
setting up traffic matrices or failure policies, debugging DSL syntax or validation errors,
8+
or asking about NetGraph scenario structure.
9+
license: MIT
10+
metadata:
11+
author: "netgraph"
12+
version: "1.0"
13+
repo: "https://github.com/networmix/NetGraph"
14+
---
15+
16+
# NetGraph DSL
17+
18+
Define network simulation scenarios in YAML format.
19+
20+
## Quick Reference
21+
22+
| Section | Purpose |
23+
|---------|---------|
24+
| `network` | Topology: nodes, links, groups, adjacency (required) |
25+
| `blueprints` | Reusable topology templates |
26+
| `components` | Hardware library for cost/power modeling |
27+
| `risk_groups` | Failure correlation groups |
28+
| `vars` | YAML anchors for value reuse |
29+
| `traffic_matrix_set` | Traffic demand definitions |
30+
| `failure_policy_set` | Failure simulation rules |
31+
| `workflow` | Analysis execution steps |
32+
| `seed` | Master seed for reproducibility |
33+
34+
## Minimal Example
35+
36+
```yaml
37+
network:
38+
nodes:
39+
A: {}
40+
B: {}
41+
links:
42+
- source: A
43+
target: B
44+
link_params:
45+
capacity: 100
46+
cost: 1
47+
```
48+
49+
## Core Patterns
50+
51+
### Nodes and Links
52+
53+
```yaml
54+
network:
55+
nodes:
56+
Seattle:
57+
attrs: # Custom attributes go here
58+
role: core
59+
risk_groups: ["RG1"]
60+
disabled: false
61+
Portland:
62+
attrs:
63+
role: edge
64+
65+
links:
66+
- source: Seattle
67+
target: Portland
68+
link_params: # Required wrapper for link parameters
69+
capacity: 100
70+
cost: 10
71+
attrs:
72+
distance_km: 280
73+
link_count: 2 # Parallel links
74+
```
75+
76+
### Node Groups
77+
78+
```yaml
79+
network:
80+
groups:
81+
leaf:
82+
node_count: 4
83+
name_template: "leaf-{node_num}"
84+
attrs:
85+
role: leaf
86+
```
87+
88+
Creates: `leaf/leaf-1`, `leaf/leaf-2`, `leaf/leaf-3`, `leaf/leaf-4`
89+
90+
### Template Syntaxes
91+
92+
| Syntax | Example | Context |
93+
|--------|---------|---------|
94+
| `[1-3]` | `dc[1-3]/rack` | Group names, risk groups |
95+
| `$var`/`${var}` | `pod${p}/leaf` | Adjacency & demand selectors |
96+
| `{node_num}` | `srv-{node_num}` | `name_template` field |
97+
98+
These are NOT interchangeable. See [REFERENCE.md](references/REFERENCE.md) for details.
99+
100+
### Bracket Expansion
101+
102+
```yaml
103+
network:
104+
groups:
105+
dc[1-3]/rack[a,b]: # Cartesian product
106+
node_count: 4
107+
name_template: "srv-{node_num}"
108+
```
109+
110+
Creates: `dc1/racka`, `dc1/rackb`, `dc2/racka`, `dc2/rackb`, `dc3/racka`, `dc3/rackb`
111+
112+
**Scope**: Bracket expansion works in group names, risk group definitions (including children), and risk group membership arrays. Component names and other fields treat brackets as literal characters.
113+
114+
### Adjacency Patterns
115+
116+
```yaml
117+
network:
118+
adjacency:
119+
- source: /leaf
120+
target: /spine
121+
pattern: mesh # Every source to every target
122+
link_params:
123+
capacity: 100
124+
125+
- source: /group_a # 4 nodes
126+
target: /group_b # 2 nodes
127+
pattern: one_to_one # Pairwise with modulo wrap (sizes must have multiple factor)
128+
```
129+
130+
### Selectors with Conditions
131+
132+
```yaml
133+
adjacency:
134+
- source:
135+
path: "/datacenter"
136+
match:
137+
logic: and # "and" or "or" (default)
138+
conditions:
139+
- attr: role
140+
operator: "=="
141+
value: leaf
142+
target: /spine
143+
pattern: mesh
144+
```
145+
146+
**Operators**: `==`, `!=`, `<`, `<=`, `>`, `>=`, `contains`, `not_contains`, `in`, `not_in`, `any_value`, `no_value`
147+
148+
### Capturing Groups for Grouping
149+
150+
```yaml
151+
# Single capture group creates groups by captured value
152+
source: "^(dc[1-3])/.*" # Groups: dc1, dc2, dc3
153+
154+
# Multiple capture groups join with |
155+
source: "^(dc\\d+)/(spine|leaf)/.*" # Groups: dc1|spine, dc1|leaf, etc.
156+
```
157+
158+
### Variable Expansion
159+
160+
```yaml
161+
adjacency:
162+
- source: "plane${p}/rack"
163+
target: "spine${s}"
164+
expand_vars:
165+
p: [1, 2]
166+
s: [1, 2, 3]
167+
expansion_mode: cartesian # or "zip" (equal-length lists required)
168+
pattern: mesh
169+
```
170+
171+
### Blueprints
172+
173+
```yaml
174+
blueprints:
175+
clos_pod:
176+
groups:
177+
leaf:
178+
node_count: 4
179+
name_template: "leaf-{node_num}"
180+
spine:
181+
node_count: 2
182+
name_template: "spine-{node_num}"
183+
adjacency:
184+
- source: /leaf
185+
target: /spine
186+
pattern: mesh
187+
link_params:
188+
capacity: 100
189+
190+
network:
191+
groups:
192+
pod[1-2]:
193+
use_blueprint: clos_pod
194+
parameters:
195+
leaf.node_count: 6 # Override defaults
196+
```
197+
198+
### Traffic Demands
199+
200+
```yaml
201+
traffic_matrix_set:
202+
production:
203+
- source: "^dc1/.*"
204+
sink: "^dc2/.*"
205+
demand: 1000
206+
mode: pairwise # or "combine"
207+
flow_policy_config: SHORTEST_PATHS_ECMP
208+
```
209+
210+
**Flow policies**: `SHORTEST_PATHS_ECMP`, `SHORTEST_PATHS_WCMP`, `TE_WCMP_UNLIM`, `TE_ECMP_16_LSP`, `TE_ECMP_UP_TO_256_LSP`
211+
212+
### Failure Policies
213+
214+
```yaml
215+
failure_policy_set:
216+
single_link:
217+
fail_risk_groups: false # Expand to shared-risk entities
218+
modes: # Weighted modes (one selected per iteration)
219+
- weight: 1.0
220+
rules:
221+
- entity_scope: link # node, link, or risk_group
222+
rule_type: choice # all, choice, or random
223+
count: 1
224+
# Optional: weight_by: capacity # Weighted sampling by attribute
225+
```
226+
227+
**Rule types**: `all` (select all matches), `choice` (sample `count`), `random` (each with `probability`)
228+
229+
### Workflow
230+
231+
```yaml
232+
workflow:
233+
- step_type: NetworkStats
234+
name: stats
235+
- step_type: MaximumSupportedDemand
236+
name: msd
237+
matrix_name: production
238+
alpha_start: 1.0
239+
resolution: 0.05
240+
- step_type: TrafficMatrixPlacement
241+
name: placement
242+
matrix_name: production
243+
failure_policy: single_link
244+
iterations: 1000
245+
alpha_from_step: msd # Reference MSD result
246+
alpha_from_field: data.alpha_star
247+
- step_type: MaxFlow
248+
source: "^(dc[1-3])$"
249+
sink: "^(dc[1-3])$"
250+
mode: pairwise
251+
failure_policy: single_link
252+
iterations: 1000
253+
baseline: true # Include no-failure baseline
254+
```
255+
256+
**Step types**: `BuildGraph`, `NetworkStats`, `MaxFlow`, `TrafficMatrixPlacement`, `MaximumSupportedDemand`, `CostPower`
257+
258+
## Common Pitfalls
259+
260+
### 1. Custom fields must go in `attrs`
261+
262+
```yaml
263+
# WRONG
264+
nodes:
265+
A:
266+
my_field: value # Error!
267+
268+
# CORRECT
269+
nodes:
270+
A:
271+
attrs:
272+
my_field: value
273+
```
274+
275+
### 2. Link parameters require `link_params` wrapper
276+
277+
```yaml
278+
# WRONG
279+
links:
280+
- source: A
281+
target: B
282+
capacity: 100 # Error!
283+
284+
# CORRECT
285+
links:
286+
- source: A
287+
target: B
288+
link_params:
289+
capacity: 100
290+
```
291+
292+
### 3. `one_to_one` requires compatible sizes
293+
294+
Sizes must have a multiple factor (4-to-2 OK, 3-to-2 ERROR).
295+
296+
### 4. Path patterns are anchored at start
297+
298+
```yaml
299+
path: "leaf" # Only matches names STARTING with "leaf"
300+
path: ".*leaf.*" # Matches "leaf" anywhere
301+
```
302+
303+
**Note**: Leading `/` is stripped and has no effect. `/leaf` and `leaf` are equivalent. All paths are relative to the current scope (blueprint instantiation path or network root).
304+
305+
### 5. Variable syntax uses `$` prefix
306+
307+
```yaml
308+
# WRONG (conflicts with regex {m,n})
309+
source: "{dc}/leaf"
310+
311+
# CORRECT
312+
source: "${dc}/leaf"
313+
```
314+
315+
### 6. `zip` requires equal-length lists
316+
317+
```yaml
318+
# WRONG
319+
expand_vars:
320+
a: [1, 2]
321+
b: [x, y, z] # Length mismatch!
322+
expansion_mode: zip
323+
```
324+
325+
### 7. Processing order matters
326+
327+
1. Groups and direct nodes created
328+
2. Node overrides applied
329+
3. Adjacency and blueprint adjacencies expanded
330+
4. Direct links created
331+
5. Link overrides applied
332+
333+
Overrides only affect entities that exist at their processing stage.
334+
335+
## Validation Checklist
336+
337+
- [ ] Custom fields inside `attrs`
338+
- [ ] Link parameters inside `link_params`
339+
- [ ] Referenced blueprints exist
340+
- [ ] Node names in direct links exist
341+
- [ ] `one_to_one` sizes have multiple factor
342+
- [ ] `zip` lists have equal length
343+
- [ ] Selectors have at least one of: `path`, `group_by`, `match`
344+
345+
## More Information
346+
347+
- [Full DSL Reference](references/REFERENCE.md) - Complete field documentation, all operators, workflow steps
348+
- [Working Examples](references/EXAMPLES.md) - 11 complete scenarios from simple to advanced

0 commit comments

Comments
 (0)