Skip to content

Commit 91b25fa

Browse files
committed
Update v0.15.0
- Added dynamic risk group creation with auto-assignment based on attribute matching and generation from unique attribute values. - Implemented risk group validation to detect undefined references and circular hierarchies at load time.
1 parent 6464476 commit 91b25fa

44 files changed

Lines changed: 4195 additions & 428 deletions

Some content is hidden

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

.claude/skills/netgraph-dsl/SKILL.md

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,30 @@ description: >
99
license: MIT
1010
metadata:
1111
author: "netgraph"
12-
version: "1.0"
12+
version: "1.1"
1313
repo: "https://github.com/networmix/NetGraph"
1414
---
1515

1616
# NetGraph DSL
1717

1818
Define network simulation scenarios in YAML format.
1919

20+
> **Quick Start**: See [Minimal Example](#minimal-example) below.
21+
> **Complete Reference**: See [references/REFERENCE.md](references/REFERENCE.md) for full documentation.
22+
23+
## Instructions
24+
25+
When working with NetGraph scenarios:
26+
27+
1. **Creating new scenarios**: Start with the [Minimal Example](#minimal-example), then add sections as needed
28+
2. **Editing existing scenarios**: Identify the relevant section (network, traffic_matrix_set, failure_policy_set, etc.)
29+
3. **Understanding selection**: Review [Selection Models](#selection-models) to understand path-based vs condition-based selection
30+
4. **Debugging issues**: Check [Common Pitfalls](#common-pitfalls) and [Validation Checklist](#validation-checklist)
31+
5. **Complex topologies**: Use [Blueprints](#blueprints) for reusable patterns
32+
6. **Failure simulation**: Define [Risk Groups](#risk-groups) before creating failure policies
33+
34+
Refer to specific sections below for detailed syntax and examples.
35+
2036
## Quick Reference
2137

2238
| Section | Purpose |
@@ -48,6 +64,28 @@ network:
4864
4965
## Core Patterns
5066
67+
### Selection Models
68+
69+
The DSL implements two distinct selection patterns:
70+
71+
**1. Path-based Node Selection** (adjacency rules, traffic demands, workflow steps)
72+
73+
- Uses regex patterns on hierarchical node names
74+
- Supports capture group-based grouping
75+
- Supports attribute-based grouping (`group_by`)
76+
- Supports attribute filtering (`match` conditions)
77+
- Supports `active_only` filtering
78+
79+
**2. Condition-based Entity Selection** (failure rules, membership rules, risk group generation)
80+
81+
- Works on nodes, links, or risk_groups (`entity_scope`)
82+
- Uses only attribute-based filtering (`conditions`)
83+
- No path/regex patterns (operates on all entities of specified type)
84+
85+
These patterns share common primitives (condition evaluation, match specification) but serve different purposes and should not be confused.
86+
87+
> **For comprehensive details** on entity creation flows, processing steps, and comparison tables, see the [Entity Creation Architecture](references/REFERENCE.md#entity-creation-architecture) section in the full reference.
88+
5189
### Nodes and Links
5290

5391
```yaml
@@ -134,7 +172,7 @@ adjacency:
134172
- source:
135173
path: "/datacenter"
136174
match:
137-
logic: and # "and" or "or" (default)
175+
logic: and # "and" or "or"; defaults vary by context (see below)
138176
conditions:
139177
- attr: role
140178
operator: "=="
@@ -145,6 +183,15 @@ adjacency:
145183

146184
**Operators**: `==`, `!=`, `<`, `<=`, `>`, `>=`, `contains`, `not_contains`, `in`, `not_in`, `any_value`, `no_value`
147185

186+
**Logic defaults by context**:
187+
188+
| Context | Default `logic` | Rationale |
189+
|---------|-----------------|-----------|
190+
| Adjacency `match` | `"or"` | Inclusive: match any condition |
191+
| Demand `match` | `"or"` | Inclusive: match any condition |
192+
| Membership rules | `"and"` | Precise: must match all conditions |
193+
| Failure rules | `"or"` | Inclusive: match any condition |
194+
148195
### Capturing Groups for Grouping
149196

150197
```yaml
@@ -226,6 +273,47 @@ failure_policy_set:
226273

227274
**Rule types**: `all` (select all matches), `choice` (sample `count`), `random` (each with `probability`)
228275

276+
### Risk Groups
277+
278+
Risk groups model failure correlation (shared infrastructure, geographic regions, vendor dependencies, or any custom domain). Three methods:
279+
280+
**Direct definition:**
281+
282+
```yaml
283+
risk_groups:
284+
- name: "RG1" # Full form
285+
- "RG2" # String shorthand (equivalent to {name: "RG2"})
286+
```
287+
288+
**Membership rules** (assign entities by attribute matching):
289+
290+
```yaml
291+
risk_groups:
292+
- name: HighCapacityLinks
293+
membership:
294+
entity_scope: link # node, link, or risk_group
295+
match:
296+
logic: and # "and" or "or" (default: "and" for membership)
297+
conditions:
298+
- attr: capacity
299+
operator: ">="
300+
value: 1000
301+
```
302+
303+
**Generate blocks** (create groups from unique attribute values):
304+
305+
```yaml
306+
risk_groups:
307+
- generate:
308+
entity_scope: node # node or link only
309+
group_by: region # Any attribute to group by
310+
name_template: "Region_${value}"
311+
```
312+
313+
**Validation:** Risk group references are validated at load time (undefined references and circular hierarchies detected).
314+
315+
See [REFERENCE.md](references/REFERENCE.md) for complete details.
316+
229317
### Workflow
230318

231319
```yaml

.claude/skills/netgraph-dsl/references/EXAMPLES.md

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,118 @@ failure_policy_set:
838838

839839
**Result**: Hierarchical risk groups with recursive child failure expansion
840840

841-
## Example 17: Additional Selector Operators
841+
## Example 17: Risk Group Membership Rules
842+
843+
Dynamically assign entities based on attributes.
844+
845+
```yaml
846+
network:
847+
nodes:
848+
core1: {attrs: {role: core, tier: 3, datacenter: dc1}}
849+
core2: {attrs: {role: core, tier: 3, datacenter: dc2}}
850+
edge1: {attrs: {role: edge, tier: 1, datacenter: dc1}}
851+
edge2: {attrs: {role: edge, tier: 1, datacenter: dc2}}
852+
links:
853+
- source: core1
854+
target: core2
855+
link_params:
856+
capacity: 1000
857+
attrs:
858+
route_type: backbone
859+
path_id: primary
860+
- source: core1
861+
target: edge1
862+
link_params: {capacity: 400}
863+
864+
risk_groups:
865+
# Assign all core tier-3 nodes
866+
- name: CoreTier3
867+
membership:
868+
entity_scope: node
869+
match:
870+
logic: and # Must match ALL conditions
871+
conditions:
872+
- attr: role
873+
operator: "=="
874+
value: core
875+
- attr: tier
876+
operator: "=="
877+
value: 3
878+
879+
# Assign links by route type
880+
- name: BackboneLinks
881+
membership:
882+
entity_scope: link
883+
match:
884+
logic: and
885+
conditions:
886+
- attr: route_type # Dot-notation for nested attrs
887+
operator: "=="
888+
value: backbone
889+
890+
# String shorthand for simple groups
891+
- "ManualGroup1"
892+
```
893+
894+
**Result**: Nodes and links automatically assigned to risk groups based on attributes
895+
896+
## Example 18: Generated Risk Groups
897+
898+
Create risk groups from unique attribute values.
899+
900+
```yaml
901+
network:
902+
nodes:
903+
srv1: {attrs: {datacenter: dc1, rack: r1}}
904+
srv2: {attrs: {datacenter: dc1, rack: r2}}
905+
srv3: {attrs: {datacenter: dc2, rack: r1}}
906+
links:
907+
- source: srv1
908+
target: srv2
909+
link_params:
910+
capacity: 100
911+
attrs:
912+
connection_type: intra_dc
913+
- source: srv2
914+
target: srv3
915+
link_params:
916+
capacity: 100
917+
attrs:
918+
connection_type: inter_dc
919+
920+
risk_groups:
921+
# Generate risk group per datacenter (from nodes)
922+
- generate:
923+
entity_scope: node
924+
group_by: datacenter
925+
name_template: "DC_${value}"
926+
attrs:
927+
generated: true
928+
type: location
929+
930+
# Generate risk group per rack (from nodes)
931+
- generate:
932+
entity_scope: node
933+
group_by: rack
934+
name_template: "Rack_${value}"
935+
936+
# Generate risk group per connection type (from links)
937+
- generate:
938+
entity_scope: link
939+
group_by: connection_type
940+
name_template: "Links_${value}"
941+
```
942+
943+
**Result**: Creates 6 risk groups:
944+
945+
- `DC_dc1` (srv1, srv2)
946+
- `DC_dc2` (srv3)
947+
- `Rack_r1` (srv1, srv3)
948+
- `Rack_r2` (srv2)
949+
- `Links_intra_dc` (link srv1→srv2)
950+
- `Links_inter_dc` (link srv2→srv3)
951+
952+
## Example 19: Additional Selector Operators
842953

843954
Demonstrating all condition operators.
844955

0 commit comments

Comments
 (0)