Add first approximation of vxlan_tunnels
This commit is contained in:
@ -1,7 +1,14 @@
|
|||||||
interfaces: map(include('interface'),key=str(matches='.*GigabitEthernet[0-9]+/[0-9]+/[0-9]+|BondEthernet[0-9]+'),required=False)
|
interfaces: map(include('interface'),key=str(matches='.*GigabitEthernet[0-9]+/[0-9]+/[0-9]+|BondEthernet[0-9]+|vxlan_tunnel[0-9]+'),required=False)
|
||||||
bondethernets: map(include('bondethernet'),key=str(matches='BondEthernet[0-9]+'),required=False)
|
bondethernets: map(include('bondethernet'),key=str(matches='BondEthernet[0-9]+'),required=False)
|
||||||
loopbacks: map(include('loopback'),key=str(matches='loop[0-9]+'),required=False)
|
loopbacks: map(include('loopback'),key=str(matches='loop[0-9]+'),required=False)
|
||||||
bridgedomains: map(include('bridgedomain'),key=str(matches='bd[0-9]+'),required=False)
|
bridgedomains: map(include('bridgedomain'),key=str(matches='bd[0-9]+'),required=False)
|
||||||
|
vxlan_tunnels: map(include('vxlan'),key=str(matches='vxlan_tunnel[0-9]+'),required=False)
|
||||||
|
---
|
||||||
|
vxlan:
|
||||||
|
description: str(exclude='\'"',required=False)
|
||||||
|
local: ip()
|
||||||
|
remote: ip()
|
||||||
|
vni: int(min=1,max=16777215)
|
||||||
---
|
---
|
||||||
bridgedomain:
|
bridgedomain:
|
||||||
description: str(exclude='\'"',required=False)
|
description: str(exclude='\'"',required=False)
|
||||||
|
42
unittest/correct-vxlan.yaml
Normal file
42
unittest/correct-vxlan.yaml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
test:
|
||||||
|
description: "A few correct examples of well formed VXLANs"
|
||||||
|
errors:
|
||||||
|
count: 0
|
||||||
|
---
|
||||||
|
vxlan_tunnels:
|
||||||
|
vxlan_tunnel0:
|
||||||
|
local: 192.0.2.1
|
||||||
|
remote: 192.0.2.2
|
||||||
|
vni: 100
|
||||||
|
|
||||||
|
vxlan_tunnel1:
|
||||||
|
local: 2001:db8::1
|
||||||
|
remote: 2001:db8::2
|
||||||
|
vni: 101
|
||||||
|
|
||||||
|
vxlan_tunnel2:
|
||||||
|
local: 2001:db8::1
|
||||||
|
remote: 2001:db8::2
|
||||||
|
vni: 102
|
||||||
|
|
||||||
|
interfaces:
|
||||||
|
GigabitEthernet1/0/0:
|
||||||
|
sub-interfaces:
|
||||||
|
100:
|
||||||
|
l2xc: vxlan_tunnel1
|
||||||
|
|
||||||
|
vxlan_tunnel0:
|
||||||
|
mtu: 9216
|
||||||
|
description: "Bridgedomain member"
|
||||||
|
|
||||||
|
vxlan_tunnel1:
|
||||||
|
l2xc: GigabitEthernet1/0/0.100
|
||||||
|
|
||||||
|
vxlan_tunnel2:
|
||||||
|
lcp: 'vxlan2'
|
||||||
|
addresses: [ 10.0.0.1/24, 2001:db8:1::1/64 ]
|
||||||
|
|
||||||
|
bridgedomains:
|
||||||
|
bd10:
|
||||||
|
mtu: 9216
|
||||||
|
interfaces: [ vxlan_tunnel0 ]
|
@ -29,6 +29,7 @@ from validator.loopback import validate_loopbacks
|
|||||||
from validator.bondethernet import validate_bondethernets
|
from validator.bondethernet import validate_bondethernets
|
||||||
from validator.interface import validate_interfaces
|
from validator.interface import validate_interfaces
|
||||||
from validator.bridgedomain import validate_bridgedomains
|
from validator.bridgedomain import validate_bridgedomains
|
||||||
|
from validator.vxlan_tunnel import validate_vxlan_tunnels
|
||||||
|
|
||||||
from yamale.validators import DefaultValidators, Validator
|
from yamale.validators import DefaultValidators, Validator
|
||||||
import ipaddress
|
import ipaddress
|
||||||
@ -121,6 +122,12 @@ class Validator(object):
|
|||||||
if not rv:
|
if not rv:
|
||||||
ret_rv = False
|
ret_rv = False
|
||||||
|
|
||||||
|
rv, msgs = validate_vxlan_tunnels(yaml)
|
||||||
|
if msgs:
|
||||||
|
ret_msgs.extend(msgs)
|
||||||
|
if not rv:
|
||||||
|
ret_rv = False
|
||||||
|
|
||||||
if ret_rv:
|
if ret_rv:
|
||||||
self.logger.debug("Semantics correctly validated")
|
self.logger.debug("Semantics correctly validated")
|
||||||
return ret_rv, ret_msgs
|
return ret_rv, ret_msgs
|
||||||
|
57
validator/vxlan_tunnel.py
Normal file
57
validator/vxlan_tunnel.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2022 Pim van Pelt
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at:
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
import logging
|
||||||
|
import validator.interface as interface
|
||||||
|
|
||||||
|
class NullHandler(logging.Handler):
|
||||||
|
def emit(self, record):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_by_name(yaml, ifname):
|
||||||
|
""" Return the VXLAN by name, if it exists. Return None otherwise. """
|
||||||
|
try:
|
||||||
|
if ifname in yaml['vxlan_tunnels']:
|
||||||
|
return yaml['vxlan_tunnels'][ifname]
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
def vni_unique(yaml, vni):
|
||||||
|
""" Return True if the VNI is unique amongst all VXLANs """
|
||||||
|
if not 'vxlan_tunnels' in yaml:
|
||||||
|
return True
|
||||||
|
|
||||||
|
ncount = 0
|
||||||
|
for ifname, iface in yaml['vxlan_tunnels'].items():
|
||||||
|
if iface['vni'] == vni:
|
||||||
|
ncount = ncount + 1
|
||||||
|
|
||||||
|
if ncount > 1:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def validate_vxlan_tunnels(yaml):
|
||||||
|
result = True
|
||||||
|
msgs = []
|
||||||
|
logger = logging.getLogger('vppcfg.validator')
|
||||||
|
logger.addHandler(NullHandler())
|
||||||
|
|
||||||
|
if not 'vxlan_tunnels' in yaml:
|
||||||
|
return result, msgs
|
||||||
|
|
||||||
|
for ifname, iface in yaml['vxlan_tunnels'].items():
|
||||||
|
logger.debug("vxlan_tunnel %s: %s" % (ifname, iface))
|
||||||
|
return result, msgs
|
Reference in New Issue
Block a user