From 60f4bb28eaac0821bcc65f2ca15a6ffdc8be6f3c Mon Sep 17 00:00:00 2001 From: Alexander Turenko Date: Tue, 16 Feb 2021 22:03:06 +0300 Subject: [PATCH] mesh_connection: bring back Unix socket support It was initially supported (since 0.6.5 release, [1]), but in 0.6.6 ([2]) we tighten arguments validation with only Internet sockets in the mind. This breaks test/cluster-py/multi.test.py test, which uses Unix sockets. Now it works again. [1]: 495dec12376f8bf6236d2c0037e090ae27d486fa ('Implement reconnection strategy class') [2]: 4dfe5f93d8ae8f5165e4cb4a1fec7a72b2218419 ('Support cluster discovery in MeshConnection') Part of #111 --- tarantool/mesh_connection.py | 73 ++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/tarantool/mesh_connection.py b/tarantool/mesh_connection.py index d1ed851b..7a1d37b2 100644 --- a/tarantool/mesh_connection.py +++ b/tarantool/mesh_connection.py @@ -35,6 +35,7 @@ def parse_uri(uri): + # TODO: Support Unix sockets. def parse_error(uri, msg): msg = 'URI "%s": %s' % (uri, msg) return None, msg @@ -59,31 +60,53 @@ def parse_error(uri, msg): def validate_address(address): - messages = [] - - if isinstance(address, dict): - if "host" not in address: - messages.append("host key must be set") - elif not isinstance(address["host"], string_types): - messages.append("host value must be string type") - - if "port" not in address: - messages.append("port is not set") - elif not isinstance(address["port"], int): - messages.append("port value must be int type") - elif address["port"] == 0: - messages.append("port value must not be zero") - elif address["port"] > 65535: - messages.append("port value must not be above 65535") - else: - messages.append("address must be a dict") - - if messages: - messages_str = ', '.join(messages) - msg = 'Address %s: %s' % (str(address), messages_str) - return None, msg - - return True, None + def format_error(address, err): + return None, 'Address %s: %s' % (str(address), err) + + if not isinstance(address, dict): + return format_error(address, 'address must be a dict') + + if 'port' not in address or address['port'] is None: + return format_error(address, 'port is not set or None') + + if isinstance(address['port'], int): + # Looks like an inet address. + + # Validate host. + if 'host' not in address or address['host'] is None: + return format_error(address, + 'host is mandatory for an inet address') + if not isinstance(address['host'], string_types): + return format_error(address, + 'host must be a string for an inet address') + + # Validate port. + if not isinstance(address['port'], int): + return format_error(address, + 'port must be an int for an inet address') + if address['port'] < 1 or address['port'] > 65535: + return format_error(address, 'port must be in range [1, 65535] ' + 'for an inet address') + + # Looks okay. + return True, None + elif isinstance(address['port'], string_types): + # Looks like a unix address. + + # Expect no host. + if 'host' in address and address['host'] is not None: + return format_error( + address, 'host must be unset or None for a unix address') + + # Validate port. + if not isinstance(address['port'], string_types): + return format_error(address, + 'port must be a string for a unix address') + + # Looks okay. + return True, None + + return format_error(address, 'port must be an int or a string') class RoundRobinStrategy(object):