def ajax_search(self, query, refresh=False): if not re.match(r'^[a-z0-9-\*\? ]+$', query): abort(403) if refresh: self.nexus_init() all_hubs = nexus.list_hub_ids() else: c = sqlite3.connect(self.db_path).cursor() c.execute('SELECT hub_id FROM Cache') all_hubs = [row[0] for row in c.fetchall()] hubs = set() for keyword in query.split(' '): keyword = '*' + keyword.strip('*') + '*' hubs.update(fnmatch.filter(all_hubs, keyword)) if len(hubs) == 1: return """ <script>window.location.href = "{}";</script> """.format(url_for('serve_status', hub_id=list(hubs)[0])) results = [] oldest_cache = arrow.utcnow() for hub_id in hubs: if refresh: data = fetch_data(hub_id, self.config) res = assess_data(data, self.config) results.append((res.hub_id, res.hub_health, res.error or res.summary)) continue c.execute('SELECT * FROM Cache WHERE hub_id=?', [hub_id]) for hub_id, hub_health, summary, cache_time in c.fetchall(): cache_time = arrow.get(cache_time, 'YYYY-MM-DD HH:mm:ss') oldest_cache = min(cache_time, oldest_cache) hub_health = { 'RED': nexus.RED, 'YELLOW': nexus.YELLOW, 'GREEN': nexus.GREEN, 'FAIL': nexus.RED }[hub_health] results.append((hub_id, hub_health, summary)) if refresh or not results: oldest_cache = None else: oldest_cache = oldest_cache.humanize() # else: oldest_cache = '{} ({})'.format( # oldest_cache.humanize(), # oldest_cache.format('YYYY-MM-DD HH:mm:ss ZZ') # ) return render_template('ajax_search.html', results=results, nexus=nexus, oldest_cache=oldest_cache, query=query)
def ajax_search(self, query, refresh=False): if not re.match(r"^[a-z0-9-\*\? ]+$", query): abort(403) if refresh: self.nexus_init() all_hubs = nexus.list_hub_ids() else: c = sqlite3.connect(self.db_path).cursor() c.execute("SELECT hub_id FROM Cache") all_hubs = [row[0] for row in c.fetchall()] hubs = set() for keyword in query.split(" "): keyword = "*" + keyword.strip("*") + "*" hubs.update(fnmatch.filter(all_hubs, keyword)) if len(hubs) == 1: return """ <script>window.location.href = "{}";</script> """.format( url_for("serve_status", hub_id=list(hubs)[0]) ) results = [] oldest_cache = arrow.utcnow() for hub_id in hubs: if refresh: data = fetch_data(hub_id, self.config) res = assess_data(data, self.config) results.append((res.hub_id, res.hub_health, res.error or res.summary)) continue c.execute("SELECT * FROM Cache WHERE hub_id=?", [hub_id]) for hub_id, hub_health, summary, cache_time in c.fetchall(): cache_time = arrow.get(cache_time, "YYYY-MM-DD HH:mm:ss") oldest_cache = min(cache_time, oldest_cache) hub_health = {"RED": nexus.RED, "YELLOW": nexus.YELLOW, "GREEN": nexus.GREEN, "FAIL": nexus.RED}[ hub_health ] results.append((hub_id, hub_health, summary)) if refresh or not results: oldest_cache = None else: oldest_cache = oldest_cache.humanize() # else: oldest_cache = '{} ({})'.format( # oldest_cache.humanize(), # oldest_cache.format('YYYY-MM-DD HH:mm:ss ZZ') # ) return render_template("ajax_search.html", results=results, nexus=nexus, oldest_cache=oldest_cache, query=query)
def fetch_data(hub_id, config): nexus.private.set_hub_id(hub_id) if hub_id not in list_hub_ids(): return NodeData(hub_id=hub_id, error="Hub ID not found.") classes_log = nexus.private.fetch_system_logs("classes") if not classes_log: return NodeData(hub_id=hub_id, error="Missing classes data.") remote_hub_id = classes_log.split(',')[0] if not remote_hub_id == hub_id: return NodeData(hub_id=hub_id, error="Mismatching hub_id?!") classes = classes_log.split(',')[1:] config_cmd = [os.path.expanduser(config["hub_config_path"])] config_cmd.append(hub_id) config_cmd.extend(classes) node_config = json.loads(subprocess.check_output(config_cmd)) timestamp = nexus.get_timestamp() if timestamp is None: return NodeData(hub_id=hub_id, error="Missing timesync data.") timestamp = arrow.get(timestamp) iwconfig_log = nexus.private.fetch_system_logs("iwconfig") if not iwconfig_log: return NodeData(hub_id=hub_id, error="Missing iwconfig data.") wifi_quality = iwconfig_log.split(',')[1] if wifi_quality == 'N/A': wifi_quality = None else: wifi_quality = int(wifi_quality) versions_log = nexus.private.fetch_system_logs("versions") if not versions_log: return NodeData(hub_id=hub_id, error="Missing versions data.") versions = versions_log.split(',') versions = dict( zip(( "timestamp", "ansible", "smart-home-config", "smarthome-deployment-blobs", "smarthome-drivers", "smarthome-hub-sync", "smarthome-reverse-tunneler", ), versions)) return NodeData(hub_id=hub_id, classes=classes, config=node_config, timestamp=timestamp, versions=versions, wifi_quality=wifi_quality)
def fetch_data(hub_id, config): nexus.private.set_hub_id(hub_id) if hub_id not in list_hub_ids(): return NodeData(hub_id=hub_id, error="Hub ID not found.") classes_log = nexus.private.fetch_system_logs("classes") if not classes_log: return NodeData(hub_id=hub_id, error="Missing classes data.") remote_hub_id = classes_log.split(',')[0] if not remote_hub_id == hub_id: return NodeData(hub_id=hub_id, error="Mismatching hub_id?!") classes = classes_log.split(',')[1:] config_cmd = [os.path.expanduser(config["hub_config_path"])] config_cmd.append(hub_id) config_cmd.extend(classes) node_config = json.loads(subprocess.check_output(config_cmd)) timestamp = nexus.get_timestamp() if timestamp is None: return NodeData(hub_id=hub_id, error="Missing timesync data.") timestamp = arrow.get(timestamp) iwconfig_log = nexus.private.fetch_system_logs("iwconfig") if not iwconfig_log: return NodeData(hub_id=hub_id, error="Missing iwconfig data.") wifi_quality = iwconfig_log.split(',')[1] if wifi_quality == 'N/A': wifi_quality = None else: wifi_quality = int(wifi_quality) versions_log = nexus.private.fetch_system_logs("versions") if not versions_log: return NodeData(hub_id=hub_id, error="Missing versions data.") versions = versions_log.split(',') versions = dict(zip(( "timestamp", "ansible", "smart-home-config", "smarthome-deployment-blobs", "smarthome-drivers", "smarthome-hub-sync", "smarthome-reverse-tunneler", ), versions)) return NodeData(hub_id=hub_id, classes=classes, config=node_config, timestamp=timestamp, versions=versions, wifi_quality=wifi_quality)
def run(self): for _ in range(5): try: nexus.init(self.config) except paramiko.SSHException: continue break else: logging.error('Could not log in') exit(1) self.log.debug('Logged in.') all_hubs = nexus.list_hub_ids() for hub_id in all_hubs: data = fetch_data(hub_id, self.config) res = assess_data(data, self.config) hub_health = { nexus.RED: 'RED', nexus.YELLOW: 'YELLOW', nexus.GREEN: 'GREEN' }[res.hub_health] if res.error: hub_health = 'FAIL' c = self.db.cursor() c.execute('SELECT * FROM Cache WHERE hub_id=?', [res.hub_id]) for _, old_health, old_summary, old_time in c.fetchall(): if old_health == hub_health: break a = arrow.get(old_time, 'YYYY-MM-DD HH:mm:ss') info = { 'hub_id': res.hub_id, 'hub_health': hub_health, 'summary': res.error or res.summary, 'time': arrow.utcnow().format('YYYY-MM-DD HH:mm:ss ZZ'), 'human_old_time': a.humanize(), 'old_time': a.format('YYYY-MM-DD HH:mm:ss ZZ'), 'old_health': old_health, 'old_summary': old_summary, 'config': data.config, } if hub_health == 'FAIL': self.log.info( "{hub_id} failed: {summary} " "[was: {old_health} - {old_time}]".format(**info)) self._send_mail(info) break # If the status went to GREEN or got worse (* -> R || G -> Y) if hub_health == 'GREEN' or hub_health == 'RED' or ( old_health == 'GREEN' and hub_health == 'YELLOW'): self.log.info( "{hub_id} is {hub_health}: {summary} " "[was: {old_health} - {old_time}]".format(**info)) self._send_mail(info) self.log.debug("{} is {}: {}".format(res.hub_id, hub_health, res.error or res.summary)) c.execute( """INSERT OR REPLACE INTO Cache (hub_id, hub_health, summary, time) VALUES (?, ?, ?, datetime('now'));""", (res.hub_id, hub_health, res.error or res.summary)) self.db.commit()
def run(self): for _ in range(5): try: nexus.init(self.config) except paramiko.SSHException: continue break else: logging.error('Could not log in') exit(1) self.log.debug('Logged in.') all_hubs = nexus.list_hub_ids() for hub_id in all_hubs: data = fetch_data(hub_id, self.config) res = assess_data(data, self.config) hub_health = { nexus.RED: 'RED', nexus.YELLOW: 'YELLOW', nexus.GREEN: 'GREEN' }[res.hub_health] if res.error: hub_health = 'FAIL' c = self.db.cursor() c.execute('SELECT * FROM Cache WHERE hub_id=?', [res.hub_id]) for _, old_health, old_summary, old_time in c.fetchall(): if old_health == hub_health: break a = arrow.get(old_time, 'YYYY-MM-DD HH:mm:ss') info = { 'hub_id': res.hub_id, 'hub_health': hub_health, 'summary': res.error or res.summary, 'time': arrow.utcnow().format('YYYY-MM-DD HH:mm:ss ZZ'), 'human_old_time': a.humanize(), 'old_time': a.format('YYYY-MM-DD HH:mm:ss ZZ'), 'old_health': old_health, 'old_summary': old_summary, 'config': data.config, } if hub_health == 'FAIL': self.log.info("{hub_id} failed: {summary} " "[was: {old_health} - {old_time}]".format(**info)) self._send_mail(info) break # If the status went to GREEN or got worse (* -> R || G -> Y) if hub_health == 'GREEN' or hub_health == 'RED' or ( old_health == 'GREEN' and hub_health == 'YELLOW'): self.log.info("{hub_id} is {hub_health}: {summary} " "[was: {old_health} - {old_time}]".format(**info)) self._send_mail(info) self.log.debug("{} is {}: {}".format( res.hub_id, hub_health, res.error or res.summary )) c.execute("""INSERT OR REPLACE INTO Cache (hub_id, hub_health, summary, time) VALUES (?, ?, ?, datetime('now'));""", ( res.hub_id, hub_health, res.error or res.summary )) self.db.commit()