blob: 93522301c41f918872233855c32cffe9899239fe [file] [log] [blame]
# Copyright (c) Facebook, Inc. and its affiliates.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree.
import re
from typing import Dict, Optional, Tuple
def _parse_rendezvous_config(config_str: str) -> Dict[str, str]:
"""
Extracts key-value pairs from a configuration string that has the format
<key1>=<value1>,...,<keyN>=<valueN>.
"""
config: Dict[str, str] = {}
if not config_str:
return config
key_values = config_str.split(",")
for kv in key_values:
key, *values = kv.split("=", 1)
if not values:
raise ValueError(f"The '{key}' rendezvous config has no value specified.")
config[key] = values[0]
return config
def _parse_hostname_and_port(
endpoint: Optional[str], default_port: int
) -> Tuple[str, int]:
"""
Extracts the hostname and the port number from an endpoint string that has
the format <hostname>:<port>.
If no hostname can be found, defaults to the loopback address 127.0.0.1.
"""
if not endpoint:
return ("127.0.0.1", default_port)
hostname, *rest = endpoint.rsplit(":", 1)
if len(rest) == 1:
if re.match(r"^[0-9]{1,5}$", rest[0]):
port = int(rest[0])
else:
port = 0
if port <= 80 or port >= 2 ** 16:
raise ValueError(
f"The rendezvous endpoint '{endpoint}' has an invalid port number '{rest[0]}'."
)
else:
port = default_port
if not re.match(r"^[\w\.:-]+$", hostname):
raise ValueError(
f"The rendezvous enpoint '{endpoint}' has an invalid hostname '{hostname}'."
)
return hostname, port