1
0
mirror of https://github.com/checktheroads/hyperglass synced 2024-05-11 05:55:08 +00:00

remove requirement for default VRF to be named default, closes #29

This commit is contained in:
checktheroads
2021-02-25 23:38:57 -07:00
parent cca6b60f09
commit e4f4eb85b0
11 changed files with 120 additions and 121 deletions

View File

@@ -21,33 +21,24 @@ from .validators import (
validate_community_input,
validate_community_select,
)
from ..config.vrf import Vrf
def get_vrf_object(vrf_name):
"""Match VRF object from VRF name.
def get_vrf_object(vrf_name: str) -> Vrf:
"""Match VRF object from VRF name."""
Arguments:
vrf_name {str} -- VRF name
Raises:
InputInvalid: Raised if no VRF is matched.
Returns:
{object} -- Valid VRF object
"""
matched = None
for vrf_obj in devices.vrf_objects:
if vrf_name is not None:
if vrf_name == vrf_obj.name or vrf_name == vrf_obj.display_name:
matched = vrf_obj
break
if vrf_name == vrf_obj._id or vrf_name == vrf_obj.display_name:
return vrf_obj
elif vrf_name == "__hyperglass_default" and vrf_obj.default:
return vrf_obj
elif vrf_name is None:
if vrf_obj.name == "default":
matched = vrf_obj
break
if matched is None:
raise InputInvalid(params.messages.vrf_not_found, vrf_name=vrf_name)
return matched
if vrf_obj.default:
return vrf_obj
raise InputInvalid(params.messages.vrf_not_found, vrf_name=vrf_name)
class Query(BaseModel):
@@ -145,7 +136,7 @@ class Query(BaseModel):
items = {
"query_location": self.query_location,
"query_type": self.query_type,
"query_vrf": self.query_vrf.name,
"query_vrf": self.query_vrf._id,
"query_target": str(self.query_target),
}
return items
@@ -156,17 +147,7 @@ class Query(BaseModel):
@validator("query_type")
def validate_query_type(cls, value):
"""Ensure query_type is enabled.
Arguments:
value {str} -- Query Type
Raises:
InputInvalid: Raised if query_type is disabled.
Returns:
{str} -- Valid query_type
"""
"""Ensure query_type is enabled."""
query = params.queries[value]
if not query.enable:
raise InputInvalid(
@@ -178,17 +159,7 @@ class Query(BaseModel):
@validator("query_location")
def validate_query_location(cls, value):
"""Ensure query_location is defined.
Arguments:
value {str} -- Unvalidated query_location
Raises:
InputInvalid: Raised if query_location is not defined.
Returns:
{str} -- Valid query_location
"""
"""Ensure query_location is defined."""
if value not in devices._ids:
raise InputInvalid(
params.messages.invalid_field,
@@ -200,17 +171,7 @@ class Query(BaseModel):
@validator("query_vrf")
def validate_query_vrf(cls, value, values):
"""Ensure query_vrf is defined.
Arguments:
value {str} -- Unvalidated query_vrf
Raises:
InputInvalid: Raised if query_vrf is not defined.
Returns:
{str} -- Valid query_vrf
"""
"""Ensure query_vrf is defined."""
vrf_object = get_vrf_object(value)
device = devices[values["query_location"]]
device_vrf = None

View File

@@ -237,7 +237,7 @@ class Device(HyperglassModel):
"""
vrfs = []
for vrf in value:
vrf_name = vrf.get("name")
vrf_default = vrf.get("default", False)
for afi in ("ipv4", "ipv6"):
vrf_afi = vrf.get(afi)
@@ -259,9 +259,7 @@ class Device(HyperglassModel):
# to make one by replacing non-alphanumeric characters
# with whitespaces and using str.title() to make each
# word look "pretty".
if vrf_name != "default" and not isinstance(
vrf.get("display_name"), StrictStr
):
if not vrf_default and not isinstance(vrf.get("display_name"), str):
new_name = vrf["name"]
new_name = re.sub(r"[^a-zA-Z0-9]", " ", new_name)
new_name = re.split(" ", new_name)
@@ -272,7 +270,7 @@ class Device(HyperglassModel):
f"Generated '{vrf['display_name']}'"
)
elif vrf_name == "default" and vrf.get("display_name") is None:
elif vrf_default and vrf.get("display_name") is None:
vrf["display_name"] = "Global"
# Validate the non-default VRF against the standard

View File

@@ -1,7 +1,8 @@
"""Validate VRF configuration variables."""
# Standard Library
from typing import List, Optional
import re
from typing import Dict, List, Optional
from ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network
# Third Party
@@ -10,18 +11,39 @@ from pydantic import (
FilePath,
StrictStr,
StrictBool,
PrivateAttr,
conint,
constr,
validator,
root_validator,
)
# Project
from hyperglass.log import log
# Local
from ..main import HyperglassModel, HyperglassModelExtra
ACLAction = constr(regex=r"permit|deny")
def find_vrf_id(values: Dict) -> str:
"""Generate (private) VRF ID."""
def generate_id(name: str) -> str:
scrubbed = re.sub(r"[^A-Za-z0-9\_\-\s]", "", name)
return "_".join(scrubbed.split()).lower()
display_name = values.get("display_name")
if display_name is None:
raise ValueError("display_name is required.")
vrf_id = generate_id(display_name)
return vrf_id
class AccessList4(HyperglassModel):
"""Validation model for IPv4 access-lists."""
@@ -195,23 +217,33 @@ class DeviceVrf6(HyperglassModelExtra):
class Vrf(HyperglassModel):
"""Validation model for per VRF/afi config in devices.yaml."""
_id: StrictStr = PrivateAttr()
name: StrictStr
display_name: StrictStr
info: Info = Info()
ipv4: Optional[DeviceVrf4]
ipv6: Optional[DeviceVrf6]
default: StrictBool = False
def __init__(self, **kwargs) -> None:
"""Set the VRF ID."""
_id = find_vrf_id(kwargs)
super().__init__(**kwargs)
self._id = _id
@root_validator
def set_dynamic(cls, values):
"""Set dynamic attributes before VRF initialization.
def set_dynamic(cls, values: Dict) -> Dict:
"""Set dynamic attributes before VRF initialization."""
Arguments:
values {dict} -- Post-validation VRF attributes
Returns:
{dict} -- VRF with new attributes set
"""
if values["name"] == "default":
log.warning(
"""You have set the VRF name to 'default'. This is no longer the way to
designate a VRF as the default (or global routing table) VRF. Instead,
add 'default: true' to the VRF definition.
"""
)
if values.get("default", False) is True:
protocol4 = "ipv4_default"
protocol6 = "ipv6_default"
@@ -227,7 +259,7 @@ class Vrf(HyperglassModel):
values["ipv6"].protocol = protocol6
values["ipv6"].version = 6
if values.get("name") == "default" and values.get("display_name") is None:
if values.get("default", False) and values.get("display_name") is None:
values["display_name"] = "Global"
return values
@@ -245,7 +277,7 @@ class Vrf(HyperglassModel):
{object} -- AFI object
"""
if i not in (4, 6):
raise AttributeError(f"Must be 4 or 6, got '{i}")
raise AttributeError(f"Must be 4 or 6, got '{i}'")
return getattr(self, f"ipv{i}")