Skip to content

Interfaces

Custom types for interfaces, both physical and logical.

LAGMember

Bases: BaseModel

A LAG member interface that consists of a name and description.

Source code in gso/utils/types/interfaces.py
class LAGMember(BaseModel):
    """A LAG member interface that consists of a name and description."""

    interface_name: str
    interface_description: str | None = None

    def __hash__(self) -> int:
        """Calculate the hash based on the interface name, so that uniqueness can be determined."""
        return hash(self.interface_name)

    @model_validator(mode="before")
    def interface_description_is_not_empty(cls, input_data: dict[str, Any]) -> dict[str, Any]:
        """Clean up input for Interface description.

        If an input form thinks the input is an empty string, it should be `None` instead.
        Otherwise, we store empty strings in the database when creating interface objects.
        """
        input_data["interface_description"] = input_data.get("interface_description") or None
        return input_data

__hash__()

Calculate the hash based on the interface name, so that uniqueness can be determined.

Source code in gso/utils/types/interfaces.py
def __hash__(self) -> int:
    """Calculate the hash based on the interface name, so that uniqueness can be determined."""
    return hash(self.interface_name)

interface_description_is_not_empty(input_data)

Clean up input for Interface description.

If an input form thinks the input is an empty string, it should be None instead. Otherwise, we store empty strings in the database when creating interface objects.

Source code in gso/utils/types/interfaces.py
@model_validator(mode="before")
def interface_description_is_not_empty(cls, input_data: dict[str, Any]) -> dict[str, Any]:
    """Clean up input for Interface description.

    If an input form thinks the input is an empty string, it should be `None` instead.
    Otherwise, we store empty strings in the database when creating interface objects.
    """
    input_data["interface_description"] = input_data.get("interface_description") or None
    return input_data

JuniperLAGMember

Bases: LAGMember

A Juniper-specific LAG member interface.

Source code in gso/utils/types/interfaces.py
class JuniperLAGMember(LAGMember):
    """A Juniper-specific LAG member interface."""

    interface_name: JuniperPhyInterface

PhysicalPortCapacity

Bases: strEnum

Physical port capacity enumerator.

An enumerator that has the different possible capacities of ports that are available to use in subscriptions.

Source code in gso/utils/types/interfaces.py
class PhysicalPortCapacity(strEnum):
    """Physical port capacity enumerator.

    An enumerator that has the different possible capacities of ports that are available to use in subscriptions.
    """

    ONE_GIGABIT_PER_SECOND = "1G"
    """1Gbps."""
    TEN_GIGABIT_PER_SECOND = "10G"
    """10Gbps."""
    HUNDRED_GIGABIT_PER_SECOND = "100G"
    """100Gbps."""
    FOUR_HUNDRED_GIGABIT_PER_SECOND = "400G"
    """400Gbps."""

ONE_GIGABIT_PER_SECOND = '1G' class-attribute instance-attribute

1Gbps.

TEN_GIGABIT_PER_SECOND = '10G' class-attribute instance-attribute

10Gbps.

HUNDRED_GIGABIT_PER_SECOND = '100G' class-attribute instance-attribute

100Gbps.

FOUR_HUNDRED_GIGABIT_PER_SECOND = '400G' class-attribute instance-attribute

400Gbps.

validate_interface_names_are_unique(interfaces)

Verify if interfaces are unique.

Raises a ValueError if the interfaces are not unique.

Parameters:

Name Type Description Default
interfaces list[LAGMember]

The list of interfaces.

required

Returns:

Type Description
list[LAGMember]

The list of interfaces

Source code in gso/utils/types/interfaces.py
def validate_interface_names_are_unique(interfaces: list[LAGMember]) -> list[LAGMember]:
    """Verify if interfaces are unique.

    Raises a `ValueError` if the interfaces are not unique.

    Args:
        interfaces: The list of interfaces.

    Returns:
        The list of interfaces
    """
    interface_names = [member.interface_name for member in interfaces]
    if len(interface_names) != len(set(interface_names)):
        msg = "Interfaces must be unique."
        raise ValueError(msg)
    return interfaces

validate_juniper_phy_interface_name(interface_name)

Validate that the provided interface name matches the expected pattern.

The expected pattern for the interface name is one of 'ge', 'et', 'xe' followed by a dash '-', then a number between 0 and 19, a forward slash '/', another number between 0 and 99, another forward slash '/', and ends with a number between 0 and 99. For example: 'xe-1/0/0'. This only applies to Juniper-brand hardware.

Parameters:

Name Type Description Default
interface_name str

Interface name to validate.

required

Returns:

Type Description
str

The interface name if match was successful, otherwise it will throw a ValueError exception.

Source code in gso/utils/types/interfaces.py
def validate_juniper_phy_interface_name(interface_name: str) -> str:
    """Validate that the provided interface name matches the expected pattern.

    The expected pattern for the interface name is one of 'ge', 'et', 'xe' followed by a dash '-',
    then a number between 0 and 19, a forward slash '/', another number between 0 and 99,
    another forward slash '/', and ends with a number between 0 and 99.
    For example: 'xe-1/0/0'. This only applies to Juniper-brand hardware.

    Args:
        interface_name: Interface name to validate.

    Returns:
        The interface name if match was successful, otherwise it will throw a ValueError exception.
    """
    pattern = re.compile(r"^(ge|et|xe)-1?\d/\d{1,2}/\d{1,2}$")
    if not bool(pattern.match(interface_name)):
        error_msg = (
            f"Invalid interface name. The interface name should be of format: xe-1/0/0, received: {interface_name}"
        )
        raise ValueError(error_msg)
    return interface_name

validate_juniper_ae_interface_name(interface_name)

Validate that the provided interface name matches the expected pattern for a LAG interface.

Interface names must match the pattern 'ae' followed by a one- or two-digit number.

Source code in gso/utils/types/interfaces.py
def validate_juniper_ae_interface_name(interface_name: str) -> str:
    """Validate that the provided interface name matches the expected pattern for a LAG interface.

    Interface names must match the pattern 'ae' followed by a one- or two-digit number.
    """
    juniper_lag_re = re.compile(r"^ae\d{1,2}$")
    if not juniper_lag_re.match(interface_name):
        msg = "Invalid LAG name, please try again."
        raise ValueError(msg)
    return interface_name

bandwidth_string_is_valid(bandwidth_string)

Expect a bandwidth definition to follow the pattern of an int followed by a single letter.

If this string does not consist of a number followed by a single

Source code in gso/utils/types/interfaces.py
def bandwidth_string_is_valid(bandwidth_string: str) -> str:
    """Expect a bandwidth definition to follow the pattern of an int followed by a single letter.

    If this string does not consist of a number followed by a single
    """
    msg = f"Expected a network capacity, e.g. 40G or 200M. Got: {bandwidth_string}"
    if len(bandwidth_string) < 2:  # noqa: PLR2004 not a magic value
        raise ValueError(msg)

    if bandwidth_string[-1:] not in set("KMGT"):
        raise ValueError(msg)

    try:
        int(bandwidth_string[:-1])  # Try parsing the bandwidth number
    except ValueError as e:
        raise ValueError(msg) from e

    return bandwidth_string