Source code for bhr_client.block_manager

import signal
import time
import random
import arrow
import datetime

WATCHDOG_TIMEOUT = 60 #seconds
UNBLOCK_INTERVAL = 30 #seconds

def shift_backwards(ts, minutes=5):
    """parse and shift a timestamp backwards 5 minutes"""
    # I hate timestamps
    nt = arrow.get(ts) - datetime.timedelta(minutes=minutes)
    value = nt.isoformat()
    # https://github.com/tomchristie/django-rest-framework/blob/cf5d401a0e60948ed0b3ad384c3f76fc30c3e222/rest_framework/fields.py#L1154
    if value.endswith('+00:00'):
        value = value[:-6] + 'Z'
    return value

class DummyStdoutBlocker:
    def __init__(self):
        pass

    def block_many(self, records):
        for r in records:
            print time.ctime(), "block", r['cidr']

    def unblock_many(self, records):
        for r in records:
            print time.ctime(), "unblock", r['block']['cidr']

[docs]class BlockManager: def __init__(self, client, blocker): self.client = client self.blocker = blocker self._added_since = '2014-09-01' def do_block(self): records = self.client.get_block_queue(timeout=UNBLOCK_INTERVAL+2, added_since=self._added_since) if records: self.blocker.block_many(records) self.client.set_blocked(records) self._added_since = shift_backwards(records[-1]['added']) return bool(records) def do_unblock(self): records = self.client.get_unblock_queue() if records: self.blocker.unblock_many(records) self.client.set_unblocked(records) return bool(records) def block_all_expected(self): """Block all addresses that are expected to be blocked This is to be used for stateless backends like ExaBGP """ blocks = self.client.get_list() return self.blocker.block_many(blocks) def run_once(self): did = self.do_unblock() did = did or self.do_block() return did
[docs] def run(self): """Run the blocker, blocking and unblocking as needed""" since_unblock = 0 while True: blocked = unblocked = False signal.alarm(self.client.timeout + WATCHDOG_TIMEOUT) if time.time() - since_unblock > UNBLOCK_INTERVAL: unblocked = self.do_unblock() since_unblock = time.time() blocked = self.do_block() if not (blocked or unblocked): time.sleep(0.1)