Beispiel #1
0
 def __read_private_ips(self, filename):
     router_private_address = defaultdict(dict)
     ip_to_bd = defaultdict(list)
     try:
         with open(filename, 'r') as f:
             private_address_binding = json.load(f)
             for subnets in private_address_binding.itervalues():
                 # Log router id in broadcast domain
                 sub = subnets.keys()
                 for rid, ip in subnets.iteritems():
                     # Enable single private address as string
                     if not is_container(ip):
                         ip = [ip]
                     # Log private addresses adjacencies
                     other = sub[:]
                     other.remove(rid)
                     for s in other:
                         router_private_address[rid][s] = ip
                     for i in ip:
                         # Register the broadcast domain for each ip
                         ip_to_bd[i] = other
     except ValueError as e:
         log.error('Incorrect private IP addresses binding file')
         log.error(str(e))
         ip_to_bd.clear()
         router_private_address.clear()
     except IOError as e:
         log.warning('Cannot read private address file')
         ip_to_bd.clear()
         router_private_address.clear()
     return router_private_address, ip_to_bd
Beispiel #2
0
def DFS(generator, consumer, generate_from=None, *elems):
    """Perform a Depth First Search (DFS).

    :param generator: The function that will generate the next set of
                     element to examinate from the current one
    :param consumer: The function that will consume one element.
                     If it returns a single iterable, feed them to the
                     generator
                     If it returns a 2-tuple (x, y), feed x to the generator
                     and yield y
    :param generate_from: A starting element to feed to the generator
    :param elems: Elements to add in the original set to visit"""
    visited = set()
    to_visit = set(elems)
    if generate_from:
        to_visit |= set(generator(generate_from))
    while to_visit:
        n = to_visit.pop()
        if n in visited:
            continue
        visited.add(n)
        ret = consumer(n)
        try:
            remains, to_yield = ret
            if to_yield:
                yield to_yield
        except TypeError:
            remains = ret
        if remains:
            if not is_container(remains):
                remains = (remains,)
            to_visit |= set(*map(generator, remains))
Beispiel #3
0
def DFS(generator, consumer, generate_from=None, *elems):
    """Perform a Depth First Search (DFS).

    :param generator: The function that will generate the next set of
                     element to examinate from the current one
    :param consumer: The function that will consume one element.
                     If it returns a single iterable, feed them to the
                     generator
                     If it returns a 2-tuple (x, y), feed x to the generator
                     and yield y
    :param generate_from: A starting element to feed to the generator
    :param elems: Elements to add in the original set to visit"""
    visited = set()
    to_visit = set(elems)
    if generate_from:
        to_visit |= set(generator(generate_from))
    while to_visit:
        n = to_visit.pop()
        if n in visited:
            continue
        visited.add(n)
        ret = consumer(n)
        try:
            remains, to_yield = ret
            if to_yield:
                yield to_yield
        except TypeError:
            remains = ret
        if remains:
            if not is_container(remains):
                remains = (remains,)
            to_visit |= set(*map(generator, remains))
Beispiel #4
0
 def add_local_route(self, router, prefix, targets, **kw):
     """Add a fake local route available for specified targets"""
     if not is_container(targets):
         targets = [targets]
     self.add_fake_route(router, prefix, target=targets, **kw)
Beispiel #5
0
 def network_for_domains(net, domains, scale_factor=1,
                         max_prefixlen=sys.maxint):
     """"Return [ ( subnet, [ intf* ] )* ]
     Assign a network prefix to every broadcast domain
     :param net: the original network to split, if this is a list, modifies
                 it to contain the list of prefixes still free
     :param domains: the list of broadcast domains
     :param scale_factor: the number of ip to assign per interface
     :param max_prefixlen: The maximal length of the prefix allocated for
                           each broadcast domain"""
     domains.sort(key=len, reverse=True)
     # We want to support allocation across multiple network prefixes
     # ip_network(ip_network(x)) is safe -- tests/test_pyaddress.py
     if not is_container(net):
         net = [ip_network(net)]
     else:
         for i, n in enumerate(net):
             net[i] = ip_network(n)
     networks = net
     # Hopefully we only allocate across prefixes in the same IP version...
     net_space = networks[0].max_prefixlen
     """We keep the networks sorted as x < y so that the bigger domains
     take the smallest network before subdividing
     The assumption is that if the domains range from the biggest to
     the smallest, and if the networks are sorted from the smallest
     to the biggest, the biggest domains will take the first network that
     is able to contain it, and split it in several subnets until it is
     restricted to its prefix.
     The next domain then is necessarily of the same size
     (reuses on of the split networks) or smaller:
     use and earlier network or split a bigger one.
     """
     # Need to setup invariant
     networks.sort(cmp=cmp_prefixlen)
     for d in domains:
         if not networks:
             log.error("No subnet left in the prefix space for all"
                       "broadcast domains")
             sys.exit(1)
         intf_count = len(d) * scale_factor
         plen = min(max_prefixlen,
                    net_space - math.ceil(math.log(2 + intf_count, 2)))
         if plen < networks[-1].prefixlen:
             raise ValueError('Could not find a subnet big enough for a '
                              'broadcast domain, aborting!')
         log.debug('Allocating prefix %s in network %s for interfaces %s',
                   plen, net, d)
         # Try to find a suitable subnet in the list
         for i, net in enumerate(networks):
             nets = []
             # if the subnet is too big for the prefix, expand it
             while plen > net.prefixlen:
                 # Get list of subnets and append to list of previous
                 # subnets as it is bigger wrt. prefixlen
                 nets.extend(net.subnets(prefixlen_diff=1))
                 net = nets.pop(-1)
             # Check if we have an appropriately-sized subnet
             if plen == net.prefixlen:
                 # Remove and return the expanded/used network
                 yield (net, d)
                 del networks[i]
                 # Insert the creadted subnets if any
                 networks.extend(nets)
                 # Sort the array again
                 networks.sort(cmp=cmp_prefixlen)
                 break