From 0560bf8a82473c62323cd3cb5e45693e6b476de4 Mon Sep 17 00:00:00 2001 From: medusa Date: Wed, 6 Aug 2025 13:58:25 -0500 Subject: [PATCH] Update tech_docs/networking/cue_jinja.md --- tech_docs/networking/cue_jinja.md | 198 +++++++++++++++++++++++++++++- 1 file changed, 194 insertions(+), 4 deletions(-) diff --git a/tech_docs/networking/cue_jinja.md b/tech_docs/networking/cue_jinja.md index 34cac9f..9ef7c15 100644 --- a/tech_docs/networking/cue_jinja.md +++ b/tech_docs/networking/cue_jinja.md @@ -195,16 +195,206 @@ package router } #validate: { - // Validation rules + // Hostname validation if !strings.HasPrefix(hostname, "RTR-") { "hostname must start with RTR-" } - + if len(hostname) > 32 { + "hostname cannot exceed 32 characters" + } + if !regexp.Match("[A-Za-z0-9-]+", hostname) { + "hostname can only contain alphanumeric characters and hyphens" + } + + // Credential validation if len(credentials.enableSecret) < 8 { "enable secret must be at least 8 characters" } - - // More validation rules... + if strings.Contains(credentials.enableSecret, " ") { + "enable secret cannot contain spaces" + } + if len(credentials.consolePassword) < 8 { + "console password must be at least 8 characters" + } + if len(credentials.vtyPassword) < 8 { + "vty password must be at least 8 characters" + } + if len(credentials.tacacsKey) < 16 { + "TACACS+ key must be at least 16 characters" + } + + // SNMP validation + if len(credentials.snmp.users) == 0 { + "at least one SNMP user must be configured" + } + for _, user in credentials.snmp.users { + if len(user.authKey) < 8 { + "SNMP auth key must be at least 8 characters for user \(user.username)" + } + if len(user.privKey) < 8 { + "SNMP priv key must be at least 8 characters for user \(user.username)" + } + } + + // Interface validation + if !net.IsIPv4(interfaces.loopback0.ip) { + "loopback0 IP must be a valid IPv4 address" + } + if interfaces.loopback0.mask != "255.255.255.255" { + "loopback0 mask must be 255.255.255.255" + } + + // WAN interface validation + if interfaces.wan.bandwidth < 1 || interfaces.wan.bandwidth > 10000 { + "WAN bandwidth must be between 1-10000 Mbps" + } + if !net.IsIPv4(interfaces.wan.ipAddress) { + "WAN IP must be a valid IPv4 address" + } + if !net.IsValidMask(interfaces.wan.subnetMask) { + "WAN subnet mask is invalid" + } + if interfaces.wan.dot1qVlan < 1 || interfaces.wan.dot1qVlan > 4094 { + "WAN VLAN must be between 1-4094" + } + + // LAN interface validation + for _, iface in interfaces.lan { + if !strings.HasPrefix(iface.name, "GigabitEthernet") && + !strings.HasPrefix(iface.name, "TenGigabitEthernet") { + "LAN interface \(iface.name) must be GigabitEthernet or TenGigabitEthernet" + } + if !net.IsIPv4(iface.ipAddress) { + "LAN interface \(iface.name) IP must be valid IPv4" + } + if iface.ospf.helloInt < 1 || iface.ospf.helloInt > 65535 { + "OSPF hello interval for \(iface.name) must be 1-65535" + } + if iface.ospf.deadInt < 1 || iface.ospf.deadInt > 65535 { + "OSPF dead interval for \(iface.name) must be 1-65535" + } + if len(iface.ospf.authKey) < 8 { + "OSPF auth key for \(iface.name) must be at least 8 characters" + } + } + + // Tunnel validation + for _, tunnel in interfaces.tunnels { + if tunnel.id < 0 || tunnel.id > 2147483647 { + "Tunnel ID \(tunnel.id) must be 0-2147483647" + } + if !net.IsIPv4(tunnel.ipAddress) { + "Tunnel \(tunnel.id) IP must be valid IPv4" + } + if tunnel.bandwidth < 1 || tunnel.bandwidth > 100000 { + "Tunnel \(tunnel.id) bandwidth must be 1-100000 Kbps" + } + if tunnel.networkId < 1 || tunnel.networkId > 4294967295 { + "NHRP network ID \(tunnel.networkId) must be 1-4294967295" + } + } + + // OSPF validation + if routing.ospf.processId < 1 || routing.ospf.processId > 65535 { + "OSPF process ID must be 1-65535" + } + if !net.IsIPv4(routing.ospf.routerId) { + "OSPF router ID must be valid IPv4" + } + if len(routing.ospf.areas) == 0 { + "at least one OSPF area must be configured" + } + for _, area in routing.ospf.areas { + if !regexp.Match("^(0|[1-9][0-9]*|[0-9]\\.[0-9]\\.[0-9]\\.[0-9])$", area.id) { + "OSPF area ID \(area.id) must be number or IP format" + } + } + + // BGP validation + if routing.bgp.asn < 1 || routing.bgp.asn > 4294967295 { + "BGP ASN must be 1-4294967295" + } + if !net.IsIPv4(routing.bgp.routerId) { + "BGP router ID must be valid IPv4" + } + if len(routing.bgp.neighbors) == 0 { + "at least one BGP neighbor must be configured" + } + for _, neighbor in routing.bgp.neighbors { + if !net.IsIPv4(neighbor.ip) { + "BGP neighbor \(neighbor.ip) must be valid IPv4" + } + } + + // QoS validation + if len(qos.classes) == 0 { + "at least one QoS class must be defined" + } + totalPercent: 0 + for _, class in qos.classes { + if strings.Contains(class.bandwidth, "percent") { + percent: int(strings.Split(class.bandwidth, " ")[2]) + totalPercent += percent + } + } + if totalPercent > 100 { + "total QoS bandwidth percentages cannot exceed 100% (current: \(totalPercent)%)" + } + if qos.shapingRate < 1 || qos.shapingRate > 10000 { + "shaping rate must be 1-10000 Mbps" + } + + // NTP validation + if len(services.ntp.servers) == 0 { + "at least one NTP server must be configured" + } + for _, server in services.ntp.servers { + if !net.IsIPv4(server) { + "NTP server \(server) must be valid IPv4" + } + } + + // DNS validation + if len(services.dns.servers) < 2 { + "at least two DNS servers should be configured" + } + for _, server in services.dns.servers { + if !net.IsIPv4(server) { + "DNS server \(server) must be valid IPv4" + } + } + + // Logging validation + if len(services.logging.hosts) == 0 { + "at least one logging host must be configured" + } + for _, host in services.logging.hosts { + if !net.IsIPv4(host) { + "logging host \(host) must be valid IPv4" + } + } + + // Security policy validation + if security.passwordPolicy.minLength < 8 { + "minimum password length must be at least 8" + } + if security.passwordPolicy.maxFail < 1 || security.passwordPolicy.maxFail > 10 { + "max authentication failures must be 1-10" + } + + // AAA method validation + if len(security.aaa.methods) == 0 { + "at least one AAA authentication method must be configured" + } + hasLoginMethod: false + for _, method in security.aaa.methods { + if method.type == "login" { + hasLoginMethod = true + } + } + if !hasLoginMethod { + "AAA must include a login authentication method" + } } ```