class IDFilter(Agent): """Listens to a certain trigger event, and emits a target event once the specified count has been reached.""" autostart = False def __init__(self, ID, target=None): Agent.__init__(self) self.target = target if target is not None else self.identifier self.dispatcher = Dispatcher() self.id = ID def handle_event(self, event): if "id" in event and event["id"] == self.id: outgoing_event = Event(type=self.target, data=event["data"]) self.dispatcher.put_event(outgoing_event)
class DispatcherTest(unittest.TestCase): def setUp(self): self.am = AgentManager() self.dispatcher = Dispatcher() self.dispatcher.daemon = True self.dispatcher.start() def test_subscription(self): agent = MockAgent() self.am.add_agent(agent) self.dispatcher.bind(agent, "test") agent.create_event() agent.start() timed_out = not agent.event_received.wait(1) if timed_out: self.fail("Event not received") def tearDown(self): AgentManager.reset_singleton() Dispatcher.reset_singleton()
def __init__(self, target=None, netmask=24): super(DeviceMonitor, self).__init__() # Initialize values self.target = target if target is not None else self.identifier self.dispatcher = Dispatcher() self.threadpool = ThreadPool(5) self.updateinterval = 30 self._known_devices = {} # Fetch network device IPs default_gateway = netifaces.gateways()["default"] if default_gateway: (gateway_ip, interface) = default_gateway[netifaces.AF_INET] self.network = ipaddress.ip_network("%s/%d" % (gateway_ip, netmask), False) else: logging.error("DeviceMonitor couldn't start, no default gateway available") self.stop()
class DeviceMonitor(Agent): autostart = True def __init__(self, target=None, netmask=24): super(DeviceMonitor, self).__init__() # Initialize values self.target = target if target is not None else self.identifier self.dispatcher = Dispatcher() self.threadpool = ThreadPool(5) self.updateinterval = 30 self._known_devices = {} # Fetch network device IPs default_gateway = netifaces.gateways()["default"] if default_gateway: (gateway_ip, interface) = default_gateway[netifaces.AF_INET] self.network = ipaddress.ip_network("%s/%d" % (gateway_ip, netmask), False) else: logging.error("DeviceMonitor couldn't start, no default gateway available") self.stop() def run(self): start_time = time.time() available_devices = set() while self._enabled: # Get current local network devices current_devices = self._get_active_devices() # Filter out new and lost devices new_devices = current_devices - available_devices lost_devices = available_devices - current_devices for (ip, hostname) in new_devices: data = {"data": {"status": "connected", "hostname": hostname}} self.dispatcher.put_event(Event(type="device_connection", data=data)) self._known_devices[hostname] = {"ip": ip, "hostname": hostname, "status": True, "ports": []} for (ip, hostname) in lost_devices: data = {"data": {"status": "disconnected", "hostname": hostname}} self.dispatcher.put_event(Event(type="device_connection", data=data)) self._known_devices[hostname]["status"] = False # Update available devices available_devices = current_devices # Check all devices open homebrain ports openports = self._get_open_ports() for item in openports: # Get past values device = self._known_devices[item[0]] currentports = item[1] prevports = set(device["ports"]) # Filter out new and lost ports newports = set(currentports) - prevports lostports = set(prevports) - set(currentports) if newports: logging.info( "New homebrain node(s) from '{}' available: {}".format(device["hostname"], str(newports)) ) if lostports: logging.info( "Homebrain node(s) from '{}' is now unavailable: {}".format(device["hostname"], str(lostports)) ) # Update to new ports device["ports"] = currentports # Wait for the next update interval while start_time + self.updateinterval > time.time(): time.sleep(1) start_time = time.time() def _get_active_devices(self): hosts = list(map(lambda h: str(h), self.network.hosts())) devices = self.threadpool.map(_is_active, hosts) return set(filter(None, devices)) def _get_open_ports(self): hosts = list(map(lambda h: str(h), self._known_devices)) portdevices = self.threadpool.map(_ports_open, hosts) return portdevices @property def known_devices(self): return self._known_devices
def __init__(self, ID, target=None): Agent.__init__(self) self.target = target if target is not None else self.identifier self.dispatcher = Dispatcher() self.id = ID
def tearDown(self): AgentManager.reset_singleton() Dispatcher.reset_singleton()
def setUp(self): self.am = AgentManager() self.dispatcher = Dispatcher() self.dispatcher.daemon = True self.dispatcher.start()
def __init__(self): super(RestListener, self).__init__() self.target = self.identifier self.dispatcher = Dispatcher() self.app = Flask(__name__, static_url_path='', static_folder=get_cwd() + '/site') # # HTTP Static Files # @self.app.route("/") @self.app.route("/<_>") @self.app.route("/<_>/<__>") @self.app.route("/<_>/<__>/<___>") def index(**_): return self.app.send_static_file("index.html") @self.app.route("/styles/<filename>") def styles(filename): return self.app.send_static_file("styles/" + filename) @self.app.route("/scripts/<filename>") def scripts(filename): return self.app.send_static_file("scripts/" + filename) @self.app.route("/templates/<filename>") def templates(filename): return self.app.send_static_file("templates/" + filename) # Agent specific static files @self.app.route("/agent/<agent>/<filename>") def agentfile(agent, filename): agentfolder = filelocation = get_cwd()+"/agents/"+agent.lower()+"/site/" return flask.send_from_directory(agentfolder, filename) # # WEB API # # TODO: Rename resource to devices @self.app.route("/api/v0/nodes") def get_nodes(): devicemonitor = None for agent in AgentManager().agents: if agent.__class__.__name__ is DeviceMonitor.__name__: devicemonitor = agent if not devicemonitor or not devicemonitor.enabled: return make_response("DeviceMonitor is not running, cannot fetch nodes", 500) else: return json.dumps(devicemonitor.known_devices) @self.app.route("/api/v0/nodes/<node_id>") def get_agent(node_id): devicemonitor = None for agent in AgentManager().agents: if agent.__class__.__name__ is DeviceMonitor.__name__: devicemonitor = agent if not devicemonitor or not devicemonitor.enabled: return make_response("DeviceMonitor is not running, cannot fetch nodes", 500) else: devices = devicemonitor.known_devices if node_id in devices: return json.dumps(devices[node_id]) else: return make_response("Resource not found", 400) @self.app.route("/api/v0/agents") def get_agents(): agents = {} for agent in AgentManager().agents: agents[agent.identifier] = agent.to_json_dict() return json.dumps(agents) @self.app.route('/api/v0/modules') def get_modules(): modules = {} for module in ModuleManager().modules: modules[module.__name__] = { "name": module.__name__, "autostart": module.autostart} return json.dumps(modules) @self.app.route('/api/v0/chains') def get_chains(): chains = {} # Not the cleanest code for tree generation, but works for agent in AgentManager().agents: if agent.target != agent.identifier: links = agent.target.split('->') prelink = chains for link in range(len(links)): i = links[link] if not i in prelink: prelink[i] = {} prelink = prelink[i] return json.dumps(chains) """EVENT API""" @self.app.route("/api/v0/event", methods=["POST"]) def post_event(): msg = request.json if type(msg) is str: event = json.loads(msg) else: event = msg self.dispatcher.put_event(event) return ""