Source code for pybsd.network

# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function, unicode_literals

import logging

import ipaddress
import six
import sortedcontainers

__logger__ = logging.getLogger('pybsd')


[docs]class Interface(object): """Describes a network interface An interface has main :py:class:`ipaddress.IPv4Interface` and a main :py:class:`ipaddress.IPv6Interface`. Any other :py:class:`ipaddress.IPvxInterface` will be added as an alias. Main addresses as used by the default :py:class:`~pybsd.handlers.BaseJailHandler` as the basis to calculate jail interfaces (see :py:class:`~pybsd.handlers.BaseJailHandler.derive_interface`). Interfaces can be checked for equality based on their name and list of ips. Parameters ---------- name : :py:class:`str` a name that identifies the interface. ips : Optional[ :py:class:`str`, :py:class:`list`[:py:class:`str`] or :py:class:`set`(:py:class:`str`) ] a single ip address or a list of ip addresses, represented as strings. Duplicates are silently ignored. The first ip added for each version will become the main ip address for this interface. """ def __init__(self, name, ips=None): #: :py:class:`str`: a name that identifies the interface. self.name = name #: :py:class:`sortedcontainers.SortedSet` ([ :py:class:`ipaddress.IPv4Interface` ]): a sorted set containing all the #: IPv4 interfaces on this physical interface. self.ifsv4 = sortedcontainers.SortedListWithKey(key=lambda x: x.ip.compressed) #: :py:class:`sortedcontainers.SortedSet` ([ :py:class:`ipaddress.IPv6Interface` ]): a sorted set containing all the #: IPv6 interfaces on this physical interface. self.ifsv6 = sortedcontainers.SortedListWithKey(key=lambda x: x.ip.compressed) #: :py:class:`ipaddress.IPv4Interface`: this interface's main IPv4 interface self.main_ifv4 = None #: :py:class:`ipaddress.IPv6Interface`: this interface's main IPv6 interface self.main_ifv6 = None ips = ips or [] self.add_ips(ips)
[docs] def add_ips(self, ips): """Adds a single ip address or a list of ip addresses, represented as strings, to the interface. None and duplicates are silently ignored. Parameters ---------- ips : :py:class:`str`, :py:class:`list`[:py:class:`str`] or :py:class:`set`(:py:class:`str`) a single ip address or a list of ip addresses, represented as strings. Duplicates are silently ignored. The first ip added for each version will become the main ip address for this interface. """ if ips: if isinstance(ips, six.string_types): ips = [ips] for _ip in ips: _if = ipaddress.ip_interface(_ip) if _if.ip.compressed not in self.ips: if _if.version == 4: self.ifsv4.add(_if) if len(self.ifsv4) == 1: self.main_ifv4 = _if else: self.ifsv6.add(_if) if len(self.ifsv6) == 1: self.main_ifv6 = _if
@property def ips(self): """:py:class:`sortedcontainers.SortedSet` ([ :py:class:`str` ]): a sorted set containing all ips on this interface.""" ips = sortedcontainers.SortedSet() return ips.update({x.ip.compressed for x in self.ifsv4 + self.ifsv6})
[docs] def __eq__(self, other): """Compares interface based on their name, and list of ips""" name_eq = self.name == other.name ifsv4_eq = self.ifsv4 == other.ifsv4 ifsv6_eq = self.ifsv6 == other.ifsv6 return name_eq and ifsv4_eq and ifsv6_eq
@property def alias_ifsv4(self): """:py:class:`sortedcontainers.SortedSet` ([ :py:class:`ipaddress.IPv4Interface` ]): a sorted set containing this \ interface's IPv4 aliases""" ifs = self.ifsv4.copy() ifs.remove(self.main_ifv4) return ifs @property def alias_ifsv6(self): """:py:class:`sortedcontainers.SortedSet` ([ :py:class:`ipaddress.IPv4Interface` ]): a sorted set containing this \ interface's IPv6 aliases""" ifs = self.ifsv6.copy() ifs.remove(self.main_ifv6) return ifs def __repr__(self): # Maps the interface's string representation to its name # # Returns # ------- # : :py:class:`str` # the interface's name return self.name