diff --git a/app/database.py b/app/database.py index c7ac77d..208f943 100644 --- a/app/database.py +++ b/app/database.py @@ -115,6 +115,18 @@ def upsert_player(p): conn.close() +def delete_players_not_in(ids): + if not ids: + return 0 + placeholders = ','.join('?' * len(ids)) + conn = _conn() + cur = conn.execute(f'DELETE FROM players WHERE id NOT IN ({placeholders})', ids) + deleted = cur.rowcount + conn.commit() + conn.close() + return deleted + + def get_all_players(): conn = _conn() rows = conn.execute('SELECT * FROM players ORDER BY name').fetchall() diff --git a/app/scheduler.py b/app/scheduler.py index 3ad49ea..9780acb 100644 --- a/app/scheduler.py +++ b/app/scheduler.py @@ -14,8 +14,12 @@ def poll_yodeck(): players = yd.get_all_screens() for p in players: db.upsert_player(p) + current_ids = [p['id'] for p in players] + removed = db.delete_players_not_in(current_ids) msg = f"Fetched {len(players)} players from Yodeck API" - db.add_log('yodeck_fetch', msg, {'count': len(players)}) + if removed: + msg += f", removed {removed} deleted player(s)" + db.add_log('yodeck_fetch', msg, {'count': len(players), 'removed': removed}) log.info(msg) # Sync host list to Zabbix after a successful fetch sync_to_zabbix(players, db.add_log) diff --git a/app/zabbix.py b/app/zabbix.py index 23622bc..02ae6cd 100644 --- a/app/zabbix.py +++ b/app/zabbix.py @@ -117,6 +117,9 @@ class ZabbixClient: def update_host_name(self, hostid, visible_name): self._call('host.update', {'hostid': hostid, 'name': visible_name}) + def delete_hosts(self, hostids): + self._call('host.delete', hostids) + # ------------------------------------------------------------------ templates def get_template_id(self, name): @@ -260,10 +263,23 @@ def sync_to_zabbix(players, add_log_fn): log.warning("Skipped host %s: %s", hostname, exc) skipped += 1 + current_hostnames = {f"yodeck-{p['id']}" for p in players} + stale = [h for h in existing.values() if h['host'] not in current_hostnames] + deleted = 0 + for h in stale: + try: + zbx.delete_hosts([h['hostid']]) + deleted += 1 + log.info("Deleted stale Zabbix host: %s", h['host']) + except Exception as exc: + log.warning("Could not delete host %s: %s", h['host'], exc) + skipped += 1 + msg = (f"Zabbix sync complete: {created} created, {updated} updated" + + (f", {deleted} deleted" if deleted else "") + (f", {skipped} skipped" if skipped else "") + f" ({len(players)} total)") - add_log_fn('zabbix_sync', msg, {'created': created, 'updated': updated, 'total': len(players)}) + add_log_fn('zabbix_sync', msg, {'created': created, 'updated': updated, 'deleted': deleted, 'total': len(players)}) log.info(msg) except Exception as exc: