icmp endpoint

This commit is contained in:
kiriharu 2021-01-04 02:51:39 +03:00
parent ec55ad216e
commit 956eebcb8c
7 changed files with 76 additions and 6 deletions

View File

@ -6,7 +6,7 @@ import config
monkey.patch_all() monkey.patch_all()
# Monkey patch SSL in requests to prevent RecursionError! DO NOT REMOVE OR MOVE! # Monkey patch SSL in requests to prevent RecursionError! DO NOT REMOVE OR MOVE!
from checkers.http import HttpChecker from checkers import HttpChecker, ICMPChecker
app = Flask(__name__) app = Flask(__name__)
@ -25,6 +25,19 @@ def http_check():
return jsonify(checker.check()) return jsonify(checker.check())
@app.route('/icmp')
@access_token_required
def icmp_check():
target = request.args.get("target", None)
if not target:
abort(400)
checker = ICMPChecker(target)
return jsonify(checker.check())
def main(): def main():
http = WSGIServer(('', config.APP_PORT), app.wsgi_app) http = WSGIServer(('', config.APP_PORT), app.wsgi_app)
http.serve_forever() http.serve_forever()

View File

@ -0,0 +1,2 @@
from .http import HttpChecker
from .icmp import ICMPChecker

View File

@ -1,11 +1,10 @@
from core.coretypes import ( from core.coretypes import (
Response, HttpCheckerResponse, APINodeInfo, Response, HttpCheckerResponse,
ResponseStatus, ErrorCodes, ErrorPayload, ResponseStatus, ErrorCodes, ErrorPayload,
) )
from requests import Session from requests import Session
from requests.exceptions import ConnectionError from requests.exceptions import ConnectionError
from .base import BaseChecker from .base import BaseChecker
from api.config import NODE_NAME, NODE_LOCATION
import time import time
import re import re

View File

@ -0,0 +1,44 @@
from core.coretypes import Response, ErrorPayload, ErrorCodes, ResponseStatus, ICMPCheckerResponse
from .base import BaseChecker
from icmplib import ping
from icmplib.exceptions import NameLookupError
class ICMPChecker(BaseChecker):
def __init__(self, target: str):
super().__init__(target)
def create_not_alive_response(self):
return Response(
status=ResponseStatus.ERROR,
payload=ErrorPayload(
code=ErrorCodes.ICMPHostNotAlive,
message="Host not available for ICMP ping"
),
node=self.node_info
)
def check(self) -> Response:
try:
host = ping(self.target)
except NameLookupError:
return self.create_not_alive_response()
# TODO: ban ping localhost
if not host.is_alive:
return self.create_not_alive_response()
return Response(
status=ResponseStatus.OK,
payload=ICMPCheckerResponse(
min_rtt=host.min_rtt,
max_rtt=host.max_rtt,
avg_rtt=host.avg_rtt,
packets_sent=host.packets_sent,
packets_received=host.packets_received,
loss=host.packet_loss,
),
node=self.node_info
)

View File

@ -9,6 +9,7 @@ python = "^3.8.2"
Flask = "^1.1.2" Flask = "^1.1.2"
gevent = "^20.12.1" gevent = "^20.12.1"
requests = "^2.25.1" requests = "^2.25.1"
icmplib = "^2.0.1"
core = {path = "../core"} core = {path = "../core"}
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]

View File

@ -11,14 +11,15 @@ class ResponseStatus(str, Enum):
ERROR = "error" ERROR = "error"
class HttpErrorCodes(IntEnum): class ErrorCodes(IntEnum):
ConnectError = 1 ConnectError = 1
ICMPHostNotAlive = 2
@dataclass @dataclass
class ErrorPayload(Payload): class ErrorPayload(Payload):
message: str message: str
code: HttpErrorCodes code: ErrorCodes
@dataclass @dataclass
@ -27,6 +28,16 @@ class HttpCheckerResponse(Payload):
time: float time: float
@dataclass
class ICMPCheckerResponse(Payload):
min_rtt: float
avg_rtt: float
max_rtt: float
packets_sent: int
packets_received: int
loss: float
@dataclass @dataclass
class APINodeInfo: class APINodeInfo:
name: str name: str

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "core" name = "core"
version = "0.5.0" version = "0.6.0"
description = "Types and other core functionality" description = "Types and other core functionality"
authors = ["kiriharu <kiriharu@yandex.ru>"] authors = ["kiriharu <kiriharu@yandex.ru>"]