Ejemplo n.º 1
0
 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
Ejemplo n.º 2
0
 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)
Ejemplo n.º 3
0
    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))
Ejemplo n.º 4
0
 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
         }))
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
 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))
Ejemplo n.º 7
0
 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,
             }
         }))
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
 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)
Ejemplo n.º 10
0
 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
     }))
Ejemplo n.º 11
0
    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))
Ejemplo n.º 12
0
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