def run(self): old_res = None for event in self.events: if event.get('Type') == 'network' and event.get('Action') in [ 'create', 'destroy' ]: networks = self.docker_client.networks() result = format_networks_result(networks) if old_res == result: continue logger.debug(f"[NETWORK_INFO] Sending networks {result}") self.ws_client.send( json.dumps({ 'id': "ID." + str(time.time()), 'executed_at': now(), 'type': 'NETWORK_INFO', 'data': result })) old_res = result if event.get('Type') == 'container' and event.get('Action') in [ 'create', 'destroy', 'stop', 'start' ]: networks = self.docker_client.containers() result = format_container_result(networks) if old_res == result: continue self.ws_client.send( json.dumps({ 'id': "ID." + str(time.time()), 'executed_at': now(), 'type': 'CONTAINER_INFO', 'data': result })) old_res = result
def run(self): ex_result = [] with IPDB() as ipdb: while not self.stop_network_watcher.is_set(): udp = psutil.net_connections(kind='udp') udp_info = [{x.laddr.ip: x.laddr.port} for x in udp] tcp = psutil.net_connections(kind='tcp') tcp_info = [{x.laddr.ip: x.laddr.port} for x in tcp] result = [] for iface in self.ifaces: intf = ipdb.interfaces[iface] for k, v in dict(intf['ipaddr']).items(): udp_ports = [ip[k] for ip in udp_info if ip.get(k)] tcp_ports = [ip[k] for ip in tcp_info if ip.get(k)] result.append({ 'agent_network_subnets': [f"{k}/{v}"], 'agent_network_iface': iface, 'agent_network_ports': { 'udp': udp_ports, 'tcp': tcp_ports }, }) status = getattr(self.ws_client.ws, 'sock') result.extend(Config.get_valid_allowed_ips()) if result != ex_result and status and status.status: self.ws_client.send( json.dumps({ 'id': "ID." + str(time.time()), 'executed_at': now(), 'type': 'HW_SERVICE_INFO', 'data': result })) ex_result = result time.sleep(3)
def run(self): while not self.stop_autoping.is_set(): pings = [] ping_res = multiping(self.hosts, count=5, interval=0.5, max_threads=2) ping_res.sort(key=lambda x: x.avg_rtt) for res in ping_res: if res.is_alive: pings.append({ "ip": res.address, "latency_ms": res.avg_rtt if res.is_alive else -1, "packet_loss": res.packet_loss if res.is_alive else 1 }) if len(pings) >= self.response_limit: break self.client.send_log( json.dumps({ 'id': "ID." + str(time.time()), 'executed_at': now(), 'type': 'AUTO_PING', 'data': { "pings": pings } })) time.sleep(int(self.interval))
def send_latency_data(self, data): self.client.send_log( json.dumps({ 'id': "ID." + str(time.time()), 'executed_at': now(), 'type': 'PEERS_LATENCY_DATA', 'data': data }))
def create_response(request, result): payload = { 'id': request['id'], 'executed_at': now(), 'type': request['type'], } if isinstance(result, dict) and ('error' in result): payload.update(result) else: payload.update({'data': result}) return json.dumps(payload)
def run(self): while not self.stop_peer_watcher.is_set(): peer_info = merged_peer_info(self.wg) if not peer_info: time.sleep(1) continue self.client.send_log( json.dumps({ 'id': "UNKNOWN", 'executed_at': now(), 'type': 'IFACES_PEERS_BW_DATA', 'data': peer_info })) time.sleep(int(self.interval))
def add_peer(self, ifname, public_key, allowed_ips, gw_ipv4, endpoint_ipv4=None, endpoint_port=None): peer_metadata = get_peer_metadata(public_key=public_key) if self.wg_kernel: try: peer_info = get_peer_info(ifname=ifname, wg=self.wg) except ValueError as e: raise WgConfException(str(e)) old_ips = set(peer_info.get(public_key, [])) - set(allowed_ips) self.routes.ip_route_del(ifname, old_ips) peer = { 'public_key': public_key, 'endpoint_addr': endpoint_ipv4, 'endpoint_port': endpoint_port, 'persistent_keepalive': 15, 'allowed_ips': allowed_ips } self.wg.set(ifname, peer=peer) statuses = self.routes.ip_route_add(ifname, allowed_ips, gw_ipv4) add_iptable_rules(allowed_ips) self.client.send_log( json.dumps({ 'id': "ID." + str(now()), 'executed_at': now(), "type": "WG_ROUTE_STATUS", "data": { "connection_id": peer_metadata.get('connection_id'), "public_key": public_key, "statuses": statuses, } }))
def run(self): ex_result = [] while not self.stop_kubernetes_watcher.is_set(): result = [] if not self.namespace_list: return for namespace in self.namespace_list: ret = self.v1.list_namespaced_service(namespace) for i in ret.items: if not i.metadata.name: continue ports = {'udp': [], 'tcp': []} if not i.spec.ports: continue ports['tcp'] = [ port.port for port in i.spec.ports if port.protocol == 'TCP' ] ports['udp'] = [ port.port for port in i.spec.ports if port.protocol == 'UDP' ] result.append({ 'agent_service_subnets': f"{i.spec.cluster_ip}/32", 'agent_service_name': f"{i.metadata.name}-{namespace}", 'agent_service_ports': ports, 'agent_service_uptime': i.metadata.creation_timestamp.isoformat(), }) status = getattr(self.ws_client.ws, 'sock') if result != ex_result and status and status.status: self.ws_client.send( json.dumps({ 'id': "ID." + str(time.time()), 'executed_at': now(), 'type': 'KUBERNETES_SERVICE_INFO', 'data': result })) ex_result = result time.sleep(10)
def send_error(self, request_id): traceback.print_exc() result = { 'error': { 'traceback': traceback.format_exc(), } } logger.error(result) if result: payload = { 'id': request_id, 'executed_at': now(), 'type': self.CMD_TYPE, } if isinstance(result, dict) and ('error' in result): payload.update(result) else: payload.update({'data': result}) payload = json.dumps(payload) self.client.send(payload)
def CONFIG_INFO(self, data, **kwargs): update_tmp_file(data, 'config_dump') self.wgconf.clear_interfaces(data.get('vpn', [])) self.wgconf.clear_peers(data.get('vpn', [])) self.wgconf.clear_unused_routes(data.get('vpn', [])) response = [] for vpn_cmd in data.get('vpn', []): try: fn = getattr(self.wgconf, vpn_cmd['fn']) result = fn(**vpn_cmd['args']) if vpn_cmd['fn'] == 'create_interface' and result and\ (vpn_cmd['args'].get('public_key') != result.get('public_key') or vpn_cmd['args'].get('listen_port') != result.get('listen_port')): response.append({'fn': vpn_cmd['fn'], 'data': result}) except WgConfException as e: logger.error(f"[CONFIG_INFO] [{str(e)}]") self.runner.send(json.dumps({ 'id': kwargs['request_id'], 'executed_at': now(), 'type': 'UPDATE_AGENT_CONFIG', 'data': response }))
def execute_payload(self, request_id, payloads): result = {} ok = {} errors = [] for payload in payloads[request_id]: if payload.get('error'): errors.append(payload['error']) else: try: fn = getattr(self.wgconf, payload['fn_name']) result = fn(**payload['fn_args']) ok.update({ "fn": payload['fn_name'], "data": result, "args": payload['fn_args'] }) except WgConfException as e: logger.error( f"[WG_EXECUTOR] failed. exception = {str(e)}, data = {payload}" ) errors.append({ payload['fn_name']: str(e), "args": payload['fn_args'] }) logger.debug(f"[WG_EXECUTOR] - Results {result}") response = { 'id': request_id, 'executed_at': now(), 'type': self.CMD_TYPE, } if errors: response.update({'error': errors, 'data': {}}) elif ok: response.update({'data': ok}) self.client.send(json.dumps(response))
class AgentRunner: STOP_MESSAGE = now() def __init__(self, ws): self.ws = ws self.queue = queue.Queue() self.active = None self.agent_api = AgentApi(self) logging.root.addHandler(PublishLogToSessionHandler(self)) def run(self): while True: message = self.queue.get() if message == self.STOP_MESSAGE: break request = json.loads(message) logger.debug(f"[RUNNER] Parsed request | {request}") try: result = self.agent_api.call(request['type'], request['data'], request['id']) except: # noqa # Catch all exceptions that not handled traceback.print_exc() result = { 'error': { 'traceback': traceback.format_exc(), 'payload': request } } logger.error(result) self.queue.task_done() logger.debug(f"[RUNNER] Result | {result}") if result: payload = self.create_response(request, result) self.send(payload) @staticmethod def create_response(request, result): payload = { 'id': request['id'], 'executed_at': now(), 'type': request['type'], } if isinstance(result, dict) and ('error' in result): payload.update(result) else: payload.update({'data': result}) return json.dumps(payload) def send(self, message): status = getattr(self.ws, 'sock') if status and status.status: logger.debug(f"[SENDING]: {message}") try: self.ws.send(message) except: pass else: logger.error("[SENDING]: websocket offline") def send_log(self, message): status = getattr(self.ws, 'sock') if status and status.status: try: self.ws.send(message) except: pass