Update tech_docs/networking/cue_jinja.md
This commit is contained in:
@@ -195,16 +195,206 @@ package router
|
|||||||
}
|
}
|
||||||
|
|
||||||
#validate: {
|
#validate: {
|
||||||
// Validation rules
|
// Hostname validation
|
||||||
if !strings.HasPrefix(hostname, "RTR-") {
|
if !strings.HasPrefix(hostname, "RTR-") {
|
||||||
"hostname must start with 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 {
|
if len(credentials.enableSecret) < 8 {
|
||||||
"enable secret must be at least 8 characters"
|
"enable secret must be at least 8 characters"
|
||||||
}
|
}
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
// More validation rules...
|
// 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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user