def parse_dcs(dcs: Optional[str]) -> Optional[Dict[str, Any]]:
    """Parse a DCS URL.

    :param dcs: the DCS URL in the format ``DCS://HOST:PORT/NAMESPACE``. ``DCS`` can be one among:

        * ``consul``
        * ``etcd``
        * ``etcd3``
        * ``exhibitor``
        * ``zookeeper``

        If ``DCS`` is not specified, assume ``etcd`` by default. If ``HOST`` is not specified, assume ``localhost`` by
        default. If ``PORT`` is not specified, assume the default port of the given ``DCS``. If ``NAMESPACE`` is not
        specified, use whatever is in config.

    :returns: ``None`` if *dcs* is ``None``, otherwise a dictionary. The dictionary represents *dcs* as if it were
        parsed from the Patroni configuration file. Additionally, if a namespace is specified in *dcs*, return a
        ``namespace`` key with the parsed value.

    :raises:
        :class:`PatroniCtlException`: if the DCS name in *dcs* is not valid.

    :Example:

        >>> parse_dcs('')
        {'etcd': {'host': 'localhost:2379'}}

        >>> parse_dcs('etcd://:2399')
        {'etcd': {'host': 'localhost:2399'}}

        >>> parse_dcs('etcd://test')
        {'etcd': {'host': 'test:2379'}}

        >>> parse_dcs('etcd3://random.com:2399')
        {'etcd3': {'host': 'random.com:2399'}}

        >>> parse_dcs('etcd3://random.com:2399/customnamespace')
        {'etcd3': {'host': 'random.com:2399'}, 'namespace': '/customnamespace'}
    """
    if dcs is None:
        return None
    elif '//' not in dcs:
        dcs = '//' + dcs

    parsed = urlparse(dcs)
    scheme = parsed.scheme
    port = int(parsed.port) if parsed.port else None

    if scheme == '':
        scheme = ([k for k, v in DCS_DEFAULTS.items() if v['port'] == port] or ['etcd'])[0]
    elif scheme not in DCS_DEFAULTS:
        raise PatroniCtlException('Unknown dcs scheme: {}'.format(scheme))

    default = DCS_DEFAULTS[scheme]
    ret = yaml.safe_load(default['template'].format(host=parsed.hostname or 'localhost', port=port or default['port']))

    if parsed.path and parsed.path.strip() != '/':
        ret['namespace'] = parsed.path.strip()

    return ret
Parse a DCS URL.

    :param dcs: the DCS URL in the format ``DCS://HOST:PORT/NAMESPACE``. ``DCS`` can be one among:

        * ``consul``
        * ``etcd``
        * ``etcd3``
        * ``exhibitor``
        * ``zookeeper``

        If ``DCS`` is not specified, assume ``etcd`` by default. If ``HOST`` is not specified, assume ``localhost`` by
        default. If ``PORT`` is not specified, assume the default port of the given ``DCS``. If ``NAMESPACE`` is not
        specified, use whatever is in config.

    :returns: ``None`` if *dcs* is ``None``, otherwise a dictionary. The dictionary represents *dcs* as if it were
        parsed from the Patroni configuration file. Additionally, if a namespace is specified in *dcs*, return a
        ``namespace`` key with the parsed value.

    :raises:
        :class:`PatroniCtlException`: if the DCS name in *dcs* is not valid.

    :Example:

        >>> parse_dcs('')
        {'etcd': {'host': 'localhost:2379'}}

        >>> parse_dcs('etcd://:2399')
        {'etcd': {'host': 'localhost:2399'}}

        >>> parse_dcs('etcd://test')
        {'etcd': {'host': 'test:2379'}}

        >>> parse_dcs('etcd3://random.com:2399')
        {'etcd3': {'host': 'random.com:2399'}}

        >>> parse_dcs('etcd3://random.com:2399/customnamespace')
        {'etcd3': {'host': 'random.com:2399'}, 'namespace': '/customnamespace'}
    
patroni/ctl.py