def api_status(req_id): """ Example:: GET /api/v1/status/3aff7567-8766-44d4-8c1a-d6c33c1e1ca2 HTTP/1.1 200 OK { "error": false, "result": { "action": "trace", "host": "2a07:e00::666", "proto": "any", "req_id": "3aff7567-8766-44d4-8c1a-d6c33c1e1ca2", "result": "Very Long String Containing Results of trace/ping etc.", "status": "finished" } } :param req_id: :return: Result format:: { error: bool - True if there's an error ( check ``message`` ), result: dict = { req_id: str = The UUID for this request to check the status of it action: str = The action you requested on the given host, host: str = The IP / hostname you requested to trace, proto: str = The protocol that was used for the trace, status: str = Either ``waiting`` or ``finished`` , result: str = A long multi-line string containing the results of the trace/ping etc. } } """ # Look up the original request details in the lg_requests hash set r = get_redis() req_attempt = r.hget('lg_requests', req_id) if not req_attempt: return json_err('NOT_FOUND') req_attempt = json.loads(req_attempt) # If there are no results for this request, just return the request details data = req_attempt # If there are results, merge them with the original request information results = r.hget('lg_results', req_id) if results is not None: results = json.loads(results) data = {**req_attempt, 'status': 'finished', **results} return jsonify(error=False, result=data)
def api_trace(proto): """ Example:: POST /api/v1/trace host=8.8.4.4 HTTP/1.1 200 OK { "error": false, "result": { "req_id": "abcd123-defa", "action": "trace", "host": "8.8.4.4", "proto": "any" } } :return: JSON dict() Result:: { error: bool - True if there's an error ( check ``message`` ), result: dict = { req_id: str = The UUID for this request to check the status of it action: str = The action you requested on the given host, host: str = The IP / hostname you requested to trace, proto: str = The protocol that will be used for the trace } } """ host = request.values.get('host', None) host = host.strip() if host is not None else None # Validate the passed data before sending it to redis + rabbitmq validators = (('NO_HOST', not host), ('INV_HOST', not validate_host(host, proto)), ('INV_PROTO', proto not in ['any', 'ipv4', 'ipv6'])) for err, check in validators: if check: return json_err(err) # Generate a unique request ID, and an action object to send via rabbitmq + store in redis req_id = str(uuid4()) _data = dict(req_id=req_id, action='trace', host=host, proto=proto, status='waiting') data = json.dumps(_data) log.debug('/api/v1/trace - host: %s req_id: %s', host, req_id) # Store the JSON action details in Redis under the request ID r = get_redis() r.hset('lg_requests', req_id, data) # Send the action details via RabbitMQ for processing by background workers chan = get_rmq_chan() chan.queue_declare(RMQ_QUEUE) chan.basic_publish(exchange='', routing_key=RMQ_QUEUE, body=data) # Return the action details to the client for status querying return jsonify(error=False, result=_data)
def queue_handler(opt): r = Runner(mq_conn=base.get_rmq(), queue=base.RMQ_QUEUE, redis=base.get_redis()) r.run()
def redis(self) -> Redis: """Obtain a Redis instance from :py:attr:`._redis` or init Redis if it's `None`""" if not self._redis: self._redis = get_redis() return self._redis