fix: checkpoint the supported schemes for connectivity (#21576)

* fix: checkpoint the supported schemes for connectivity

This PR implements a gateway + error that clearly hints the operator at
a misconfigured system during runtime.

Particularity, against the multiple library-provided ways of configuring
redis connection strings (in python), this hard stops if an unsupported
one is chosen by accident.

* fix: remove unknown protocol

---------

Co-authored-by: Ankush Menat <ankushmenat@gmail.com>
This commit is contained in:
David Arnold 2023-07-15 00:35:29 -05:00 committed by GitHub
parent 5c4f6c64c6
commit 2ccab0d625
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 5 deletions

View file

@ -11,6 +11,10 @@ class SiteNotSpecifiedError(Exception):
super(Exception, self).__init__(self.message)
class UrlSchemeNotSupported(Exception):
pass
class ValidationError(Exception):
http_status_code = 417

View file

@ -2,15 +2,21 @@ import socket
from urllib.parse import urlparse
from frappe import get_conf
from frappe.exceptions import UrlSchemeNotSupported
REDIS_KEYS = ("redis_cache", "redis_queue")
def is_open(ip, port, timeout=10):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def is_open(scheme, hostname, port, timeout=10):
if scheme in ["redis", "postgres", "mariadb"]:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn = (hostname, port)
else:
raise UrlSchemeNotSupported(scheme)
s.settimeout(timeout)
try:
s.connect((ip, int(port)))
s.connect(conn)
s.shutdown(socket.SHUT_RDWR)
return True
except OSError:
@ -24,7 +30,7 @@ def check_database():
db_type = config.get("db_type", "mariadb")
db_host = config.get("db_host", "localhost")
db_port = config.get("db_port", 3306 if db_type == "mariadb" else 5432)
return {db_type: is_open(db_host, db_port)}
return {db_type: is_open(db_type, db_host, db_port)}
def check_redis(redis_services=None):
@ -33,7 +39,7 @@ def check_redis(redis_services=None):
status = {}
for srv in services:
url = urlparse(config[srv])
status[srv] = is_open(url.hostname, url.port)
status[srv] = is_open(url.scheme, url.hostname, url.port)
return status