From 2ccab0d6251eab6ac5836ab4d3715a985a954d82 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Sat, 15 Jul 2023 00:35:29 -0500 Subject: [PATCH] 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 --- frappe/exceptions.py | 4 ++++ frappe/utils/connections.py | 16 +++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/frappe/exceptions.py b/frappe/exceptions.py index 26c323352d..8dbd778a7d 100644 --- a/frappe/exceptions.py +++ b/frappe/exceptions.py @@ -11,6 +11,10 @@ class SiteNotSpecifiedError(Exception): super(Exception, self).__init__(self.message) +class UrlSchemeNotSupported(Exception): + pass + + class ValidationError(Exception): http_status_code = 417 diff --git a/frappe/utils/connections.py b/frappe/utils/connections.py index fcca8593ad..ce8b4eba0e 100644 --- a/frappe/utils/connections.py +++ b/frappe/utils/connections.py @@ -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