add UML, fix structure
This commit is contained in:
@@ -1,8 +0,0 @@
|
|||||||
@startuml
|
|
||||||
|
|
||||||
class Device {
|
|
||||||
+id: string
|
|
||||||
+name: string
|
|
||||||
+model: string
|
|
||||||
+getInterfaces()
|
|
||||||
}
|
|
||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
+79
@@ -0,0 +1,79 @@
|
|||||||
|
@startuml
|
||||||
|
|
||||||
|
' ===========================
|
||||||
|
' Abstract base class
|
||||||
|
' ===========================
|
||||||
|
|
||||||
|
abstract class Device {
|
||||||
|
- name : String
|
||||||
|
- mgmtIP : String
|
||||||
|
- interfaces : Interface[*]
|
||||||
|
}
|
||||||
|
|
||||||
|
Device "1" o-- "0..*" Interface : has >
|
||||||
|
|
||||||
|
' ===========================
|
||||||
|
' Device Types
|
||||||
|
' ===========================
|
||||||
|
|
||||||
|
class Host {
|
||||||
|
- operatingSystem : String
|
||||||
|
}
|
||||||
|
|
||||||
|
class Router {
|
||||||
|
- routingTable : Map
|
||||||
|
- routingProtocols : List
|
||||||
|
}
|
||||||
|
|
||||||
|
class Switch {
|
||||||
|
- macTable : Map
|
||||||
|
- vlanDatabase : Map
|
||||||
|
}
|
||||||
|
|
||||||
|
Device <|-- Host
|
||||||
|
Device <|-- Router
|
||||||
|
Device <|-- Switch
|
||||||
|
|
||||||
|
' ===========================
|
||||||
|
' Interfaces
|
||||||
|
' ===========================
|
||||||
|
|
||||||
|
class Interface {
|
||||||
|
- name : String
|
||||||
|
- ipAddress : String
|
||||||
|
- macAddress : String
|
||||||
|
- speed : String
|
||||||
|
- duplex : String
|
||||||
|
}
|
||||||
|
|
||||||
|
class VirtualInterface {
|
||||||
|
- vlanId : Integer
|
||||||
|
- parentPhysical : Interface
|
||||||
|
}
|
||||||
|
|
||||||
|
Interface <|-- VirtualInterface
|
||||||
|
|
||||||
|
' ===========================
|
||||||
|
' Physical Links
|
||||||
|
' ===========================
|
||||||
|
|
||||||
|
class Wire {
|
||||||
|
- type : String
|
||||||
|
- endpoints : Interface[2]
|
||||||
|
- bandwidth : String
|
||||||
|
}
|
||||||
|
|
||||||
|
Wire "1" -- "2" Interface : connects >
|
||||||
|
|
||||||
|
' ===========================
|
||||||
|
' Optional: Networks / Subnets
|
||||||
|
' ===========================
|
||||||
|
|
||||||
|
class Network {
|
||||||
|
- cidr : String
|
||||||
|
- gateway : String
|
||||||
|
}
|
||||||
|
|
||||||
|
Network "1" o-- "0..*" Interface : membership >
|
||||||
|
|
||||||
|
@enduml
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 186 KiB |
@@ -0,0 +1,160 @@
|
|||||||
|
# yaml-language-server: $schema=./topology-schema.json
|
||||||
|
schema: asvk.topology/1.0
|
||||||
|
meta:
|
||||||
|
id: "string"
|
||||||
|
title: "string"
|
||||||
|
description: "string"
|
||||||
|
|
||||||
|
provider:
|
||||||
|
name: virtualbox # virtualbox | kvm | container
|
||||||
|
defaults:
|
||||||
|
cpu: 1
|
||||||
|
ram_mb: 512
|
||||||
|
disk_gb: 8
|
||||||
|
os_image: "debian-12-cloud.qcow2"
|
||||||
|
nic_model: virtio
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
routing:
|
||||||
|
stack: bird # bird | frr | linux
|
||||||
|
protocols_enabled: []
|
||||||
|
switch:
|
||||||
|
impl: linux-bridge # linux-bridge | ovs
|
||||||
|
firewall:
|
||||||
|
impl: nftables # nftables | none
|
||||||
|
mgmt:
|
||||||
|
ssh_user: "lab"
|
||||||
|
ssh_key: "~/.ssh/id_rsa.pub"
|
||||||
|
|
||||||
|
variables: # for templates
|
||||||
|
asn: 65000
|
||||||
|
domain: "lab.local"
|
||||||
|
|
||||||
|
networks: # L2 / L3 / VLAN trunks
|
||||||
|
- id: lan1
|
||||||
|
type: l2 # l2 | l3
|
||||||
|
mtu: 1500
|
||||||
|
- id: lan13
|
||||||
|
type: l2
|
||||||
|
- id: trunk1
|
||||||
|
type: l2
|
||||||
|
vlan:
|
||||||
|
mode: trunk
|
||||||
|
allowed: [4, 8]
|
||||||
|
- id: mgmt
|
||||||
|
type: l3
|
||||||
|
cidr: 192.168.100.0/24
|
||||||
|
dhcp: false
|
||||||
|
|
||||||
|
nodes: # nodes (VM/containers)
|
||||||
|
- name: R1
|
||||||
|
role: router # router | switch | host
|
||||||
|
resources:
|
||||||
|
cpu: 1
|
||||||
|
ram_mb: 512
|
||||||
|
mgmt:
|
||||||
|
ip: 192.168.100.11/24
|
||||||
|
gw: 192.168.100.1
|
||||||
|
net: mgmt
|
||||||
|
interfaces: # order matters: eth1 ↔ adapter2 and so on
|
||||||
|
- name: eth1
|
||||||
|
network: lan13
|
||||||
|
addresses: ["10.0.13.1/24"]
|
||||||
|
- name: eth0 # MGMT
|
||||||
|
network: mgmt
|
||||||
|
routing:
|
||||||
|
stack: bird # inherited from defaults, can be omitted
|
||||||
|
protocols:
|
||||||
|
static:
|
||||||
|
routes:
|
||||||
|
- to: 0.0.0.0/0
|
||||||
|
via: 10.0.13.3
|
||||||
|
ospf: # if needed
|
||||||
|
enabled: false
|
||||||
|
rip:
|
||||||
|
enabled: false
|
||||||
|
services: # servers/daemons of the host
|
||||||
|
- name: sshd
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
switching: # L2 config for switch nodes
|
||||||
|
- node: S1
|
||||||
|
impl: linux-bridge # linux-bridge | ovs
|
||||||
|
bridges:
|
||||||
|
- name: br0
|
||||||
|
ports:
|
||||||
|
- if: eth1 # to trunk1
|
||||||
|
vlan:
|
||||||
|
mode: trunk
|
||||||
|
allowed: [4, 8]
|
||||||
|
- if: eth2 # access → VLAN 4
|
||||||
|
vlan:
|
||||||
|
mode: access
|
||||||
|
vid: 4
|
||||||
|
- if: eth3 # access → VLAN 8
|
||||||
|
vlan:
|
||||||
|
mode: access
|
||||||
|
vid: 8
|
||||||
|
svis: # VLAN management interfaces (SVI)
|
||||||
|
- vid: 4
|
||||||
|
ifname: br0.4
|
||||||
|
addresses: ["10.0.4.254/24"]
|
||||||
|
|
||||||
|
firewall: # High-level ACL-> to nftables
|
||||||
|
- node: R2
|
||||||
|
rules:
|
||||||
|
- id: allow-ospf
|
||||||
|
match:
|
||||||
|
in_if: eth1
|
||||||
|
ip_proto: ospf
|
||||||
|
action: accept
|
||||||
|
- id: telnet-from-R1-to-S1
|
||||||
|
match:
|
||||||
|
src: 10.0.13.1/32
|
||||||
|
dst: 10.0.4.254/32
|
||||||
|
l4: { proto: tcp, dport: 23 }
|
||||||
|
action: accept
|
||||||
|
- id: ftp-from-R3-to-S2
|
||||||
|
match:
|
||||||
|
src: 10.0.13.3/32
|
||||||
|
dst: 10.0.6.254/32
|
||||||
|
l4: { proto: tcp, dports: [20, 21] }
|
||||||
|
action: accept
|
||||||
|
- id: drop-rest
|
||||||
|
action: drop
|
||||||
|
|
||||||
|
profiles: # overlays - patches on top of the base description
|
||||||
|
- name: "all-frr"
|
||||||
|
description: "Switch all control-plane to FRR"
|
||||||
|
patches:
|
||||||
|
- op: replace
|
||||||
|
path: /defaults/routing/stack
|
||||||
|
value: frr
|
||||||
|
- name: "mix-bird-frr-ospf"
|
||||||
|
description: "BIRD by default, but OSPF on R2 via FRR"
|
||||||
|
patches:
|
||||||
|
- op: add
|
||||||
|
path: /nodes
|
||||||
|
where:
|
||||||
|
name: R2
|
||||||
|
patch:
|
||||||
|
routing:
|
||||||
|
protocols:
|
||||||
|
ospf:
|
||||||
|
enabled: true
|
||||||
|
impl: frr
|
||||||
|
- name: "switch-ovs"
|
||||||
|
patches:
|
||||||
|
- op: replace
|
||||||
|
path: /defaults/switch/impl
|
||||||
|
value: ovs
|
||||||
|
|
||||||
|
tests: # tests (expected result)
|
||||||
|
- name: ping-R1-to-R3
|
||||||
|
from: R1
|
||||||
|
to: 10.0.13.3
|
||||||
|
expect: success
|
||||||
|
- name: ping-VLAN-4-R1-to-R3
|
||||||
|
from: R1
|
||||||
|
to: 10.0.4.1
|
||||||
|
expect: success
|
||||||
@@ -0,0 +1,607 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"$id": "https://github.com/asvk-topology/schema/1.0",
|
||||||
|
"title": "ASVK Topology Configuration Schema",
|
||||||
|
"description": "JSON Schema for ASVK topology configuration files",
|
||||||
|
"type": "object",
|
||||||
|
"required": ["schema", "meta", "provider", "nodes"],
|
||||||
|
"properties": {
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Schema identifier",
|
||||||
|
"pattern": "^asvk\\.topology/[0-9]+\\.[0-9]+$",
|
||||||
|
"examples": ["asvk.topology/1.0"]
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Metadata for the topology configuration",
|
||||||
|
"required": ["id", "title"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Unique identifier for the topology",
|
||||||
|
"pattern": "^[a-zA-Z0-9_-]+$"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Human-readable name for the topology"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Detailed description of the topology"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Provider configuration for VMs/containers",
|
||||||
|
"required": ["name"],
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Provider name",
|
||||||
|
"enum": ["virtualbox", "kvm", "container"]
|
||||||
|
},
|
||||||
|
"defaults": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Default resource allocation",
|
||||||
|
"properties": {
|
||||||
|
"cpu": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Default CPU cores",
|
||||||
|
"minimum": 1,
|
||||||
|
"default": 1
|
||||||
|
},
|
||||||
|
"ram_mb": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Default RAM in MB",
|
||||||
|
"minimum": 128,
|
||||||
|
"default": 512
|
||||||
|
},
|
||||||
|
"disk_gb": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Default disk size in GB",
|
||||||
|
"minimum": 1,
|
||||||
|
"default": 8
|
||||||
|
},
|
||||||
|
"os_image": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Default OS image"
|
||||||
|
},
|
||||||
|
"nic_model": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Default NIC model",
|
||||||
|
"enum": ["virtio", "e1000", "rtl8139"]
|
||||||
|
},
|
||||||
|
"promiscuous": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Promiscuous mode setting",
|
||||||
|
"enum": ["deny", "allow-vms", "allow-all"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"images": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Custom images for different node types",
|
||||||
|
"properties": {
|
||||||
|
"router": { "type": "string" },
|
||||||
|
"switch": { "type": "string" },
|
||||||
|
"host": { "type": "string" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaults": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Default behavior and software configuration",
|
||||||
|
"properties": {
|
||||||
|
"routing": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"stack": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["bird", "frr", "linux"],
|
||||||
|
"default": "bird"
|
||||||
|
},
|
||||||
|
"protocols_enabled": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["ospf", "rip", "bgp", "static"]
|
||||||
|
},
|
||||||
|
"default": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"switch": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"impl": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["linux-bridge", "ovs"],
|
||||||
|
"default": "linux-bridge"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"firewall": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"impl": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["nftables", "none"],
|
||||||
|
"default": "nftables"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mgmt": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"ssh_user": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "lab"
|
||||||
|
},
|
||||||
|
"ssh_key": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Path to SSH public key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"variables": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Global variables that can be referenced in templates",
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
|
"networks": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Network definitions (L2 domains, L3 networks, VLAN trunks)",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id", "type"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Unique network identifier",
|
||||||
|
"pattern": "^[a-zA-Z0-9_-]+$"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["l2", "l3"],
|
||||||
|
"description": "Network type"
|
||||||
|
},
|
||||||
|
"mtu": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "MTU for the network",
|
||||||
|
"minimum": 68,
|
||||||
|
"maximum": 9000,
|
||||||
|
"default": 1500
|
||||||
|
},
|
||||||
|
"cidr": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "CIDR notation for L3 networks",
|
||||||
|
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$"
|
||||||
|
},
|
||||||
|
"dhcp": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Enable DHCP on this network",
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
|
"vlan": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "VLAN configuration for trunk ports",
|
||||||
|
"properties": {
|
||||||
|
"mode": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["access", "trunk"]
|
||||||
|
},
|
||||||
|
"allowed": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 4094
|
||||||
|
},
|
||||||
|
"description": "Allowed VLAN IDs on trunk"
|
||||||
|
},
|
||||||
|
"vid": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "Native VLAN ID for access ports",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 4094
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nodes": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Node definitions (VMs/containers)",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name", "role"],
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Node name",
|
||||||
|
"pattern": "^[a-zA-Z0-9_-]+$"
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["router", "switch", "host"],
|
||||||
|
"description": "Node role/type"
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "OS image for the node (can reference provider.images)"
|
||||||
|
},
|
||||||
|
"resources": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"cpu": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
},
|
||||||
|
"ram_mb": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 128
|
||||||
|
},
|
||||||
|
"disk_gb": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mgmt": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Management network configuration",
|
||||||
|
"properties": {
|
||||||
|
"ip": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$"
|
||||||
|
},
|
||||||
|
"gw": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}$"
|
||||||
|
},
|
||||||
|
"net": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"interfaces": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Network interfaces (order matters)",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name"],
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^(eth[0-9]+|lo)$"
|
||||||
|
},
|
||||||
|
"network": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"loopback": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Indicates if this is a loopback interface"
|
||||||
|
},
|
||||||
|
"addresses": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"required": ["network"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"required": ["loopback"],
|
||||||
|
"properties": {
|
||||||
|
"loopback": { "const": true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"routing": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"stack": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["bird", "frr", "linux"]
|
||||||
|
},
|
||||||
|
"protocols": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"static": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"routes": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["to", "via"],
|
||||||
|
"properties": {
|
||||||
|
"to": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])|0\\.0\\.0\\.0/0$"
|
||||||
|
},
|
||||||
|
"via": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}$"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ospf": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enabled": { "type": "boolean", "default": false },
|
||||||
|
"impl": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["bird", "frr"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rip": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enabled": { "type": "boolean", "default": false }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bgp": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enabled": { "type": "boolean", "default": false },
|
||||||
|
"asn": { "type": "integer" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name"],
|
||||||
|
"properties": {
|
||||||
|
"name": { "type": "string" },
|
||||||
|
"enabled": { "type": "boolean", "default": true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"switching": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "L2 switching configuration",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["node", "impl"],
|
||||||
|
"properties": {
|
||||||
|
"node": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Switch node name"
|
||||||
|
},
|
||||||
|
"impl": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["linux-bridge", "ovs"]
|
||||||
|
},
|
||||||
|
"bridges": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name"],
|
||||||
|
"properties": {
|
||||||
|
"name": { "type": "string" },
|
||||||
|
"ports": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["if"],
|
||||||
|
"properties": {
|
||||||
|
"if": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^eth[0-9]+$"
|
||||||
|
},
|
||||||
|
"vlan": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"mode": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["access", "trunk"]
|
||||||
|
},
|
||||||
|
"allowed": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 4094
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"vid": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 4094
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"svis": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Switched Virtual Interfaces (SVI)",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["vid", "ifname"],
|
||||||
|
"properties": {
|
||||||
|
"vid": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 4094
|
||||||
|
},
|
||||||
|
"ifname": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[a-zA-Z0-9._-]+$"
|
||||||
|
},
|
||||||
|
"addresses": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}/([0-9]|[1-2][0-9]|3[0-2])$"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"firewall": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Firewall configuration",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["node", "rules"],
|
||||||
|
"properties": {
|
||||||
|
"node": { "type": "string" },
|
||||||
|
"rules": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["id", "action"],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^[a-zA-Z0-9_-]+$"
|
||||||
|
},
|
||||||
|
"match": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"in_if": { "type": "string" },
|
||||||
|
"out_if": { "type": "string" },
|
||||||
|
"src": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}(/([0-9]|[1-2][0-9]|3[0-2]))?$"
|
||||||
|
},
|
||||||
|
"dst": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}(/([0-9]|[1-2][0-9]|3[0-2]))?$"
|
||||||
|
},
|
||||||
|
"ip_proto": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["tcp", "udp", "icmp", "ospf", "all"]
|
||||||
|
},
|
||||||
|
"l4": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"proto": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["tcp", "udp"]
|
||||||
|
},
|
||||||
|
"sport": {
|
||||||
|
"type": ["integer", "array"],
|
||||||
|
"items": { "type": "integer" },
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 65535
|
||||||
|
},
|
||||||
|
"dport": {
|
||||||
|
"type": ["integer", "array"],
|
||||||
|
"items": { "type": "integer" },
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 65535
|
||||||
|
},
|
||||||
|
"dports": {
|
||||||
|
"type": ["integer", "array"],
|
||||||
|
"items": { "type": "integer" },
|
||||||
|
"minimum": 1,
|
||||||
|
"maximum": 65535
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"action": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["accept", "drop", "reject"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"profiles": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Configuration profiles/overlays",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name", "patches"],
|
||||||
|
"properties": {
|
||||||
|
"name": { "type": "string" },
|
||||||
|
"description": { "type": "string" },
|
||||||
|
"patches": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["op", "path"],
|
||||||
|
"properties": {
|
||||||
|
"op": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["add", "replace", "remove"]
|
||||||
|
},
|
||||||
|
"path": { "type": "string" },
|
||||||
|
"value": true,
|
||||||
|
"where": {
|
||||||
|
"type": "object",
|
||||||
|
"description": "Conditional matching for patches"
|
||||||
|
},
|
||||||
|
"patch": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tests": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Validation tests",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["name", "from", "to", "expect"],
|
||||||
|
"properties": {
|
||||||
|
"name": { "type": "string" },
|
||||||
|
"from": { "type": "string" },
|
||||||
|
"to": {
|
||||||
|
"type": ["string", "object"],
|
||||||
|
"properties": {
|
||||||
|
"ip": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}$"
|
||||||
|
},
|
||||||
|
"node": { "type": "string" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"expect": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^(success|failure|timeout|via .*)$"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user