#!/usr/bin/env python3 """ This is a lightweight web service which will retrieve a peer list from a Monero node, determine GeoIP information, and return a list of metrics in a Prometheus compatible structure. Use it to start plotting maps of active node connections. """ import socket, struct from os import environ as env import requests import geoip2.database from flask import Flask, make_response app = Flask(__name__) NODE_HOST = env.get('NODE_HOST', 'wownerod') NODE_PORT = env.get('NODE_PORT', 34570) def ipfi(i: int) -> str: """Takes an unsigned integer and converts it to an IP address. """ ip = socket.inet_ntoa(struct.pack('!L', i)) return ip def get_geoip(ip): """Takes an IP address and determines GeoIP data""" with geoip2.database.Reader("./geoip.mmdb") as reader: return reader.city(ip) @app.route("/metrics") def nodes(): """Return all nodes""" peers = list() peer_list = requests.get(f'http://{NODE_HOST}:{NODE_PORT}/get_peer_list').json() def add_peer(host, status): geo = get_geoip(host) geostr = 'geoip{{latitude="{lat}", longitude="{lon}", country_code="{country_code}", country_name="{country_name}", status="{status}"}} 1' if geostr not in peers: peers.append(geostr.format( lat=geo.location.latitude, lon=geo.location.longitude, country_code=geo.continent.code, country_name=geo.continent.names['en'], status=status )) for peer in peer_list['gray_list']: if peer.get('host'): add_peer(peer['host'], 'gray') for peer in peer_list['white_list']: if peer.get('host'): add_peer(peer['host'], 'white') data = '\n'.join(peers) response = make_response(data, 200) response.mimetype = "text/plain" return response