def restart(cluster_name: str, group: Optional[int], member_names: List[str],
            force: bool, role: CtlPostgresqlRole, p_any: bool, scheduled: Optional[str], version: Optional[str],
            pending: bool, timeout: Optional[str]) -> None:
    """Process ``restart`` command of ``patronictl`` utility.

    Restart Postgres on cluster members based on given filters.

    :param cluster_name: name of the Patroni cluster.
    :param group: filter which Citus group we should restart members. Refer to the module note for more details.
    :param member_names: name of the members that should be restarted.
    :param force: perform the restart without asking for confirmations.
    :param role: role to filter members. See :func:`get_all_members` for available options.
    :param p_any: restart a single and random member among the ones that match the given filters.
    :param scheduled: timestamp when the restart should be scheduled to occur. If ``now`` restart immediately.
    :param version: restart only members which Postgres version is less than *version*.
    :param pending: restart only members that are flagged as ``pending restart``.
    :param timeout: timeout for the restart operation. If timeout is reached a failover may occur in the cluster.

    :raises:
        :class:`PatroniCtlException`: if:
            * *scheduled* could not be parsed; or
            * *version* could not be parsed; or
            * a restart is attempted against a cluster that is in maintenance mode.
    """
    cluster = get_dcs(cluster_name, group).get_cluster()

    members = get_members(cluster, cluster_name, member_names, role, force, 'restart', False, group=group)
    if scheduled is None and not force:
        next_hour = (datetime.datetime.now() + datetime.timedelta(hours=1)).strftime('%Y-%m-%dT%H:%M')
        scheduled = click.prompt('When should the restart take place (e.g. ' + next_hour + ') ',
                                 type=str, default='now')

    scheduled_at = parse_scheduled(scheduled)

    content: Dict[str, Any] = {}
    if pending:
        content['restart_pending'] = True
        # For scheduled restarts we don't filter the members now. If they really need a restart might change
        # until the scheduled time.
        if not scheduled_at:
            members = [m for m in members if m.data.get('pending_restart', False)]

    if p_any:
        random.shuffle(members)
        members = members[:1]

    confirm_members_action(members, force, 'restart', scheduled_at, pending)

    if version is None and not force:
        version = click.prompt('Restart if the PostgreSQL version is less than provided (e.g. 9.5.2) ',
                               type=str, default='')

    if version:
        try:
            postgres_version_to_int(version)
        except PatroniException as e:
            raise PatroniCtlException(e.value)

        content['postgres_version'] = version

    if scheduled_at:
        if global_config.from_cluster(cluster).is_paused:
            raise PatroniCtlException("Can't schedule restart in the paused state")
        content['schedule'] = scheduled_at.isoformat()

    if timeout is not None:
        content['timeout'] = timeout

    for member in members:
        if 'schedule' in content:
            if force and member.data.get('scheduled_restart'):
                r = request_patroni(member, 'delete', 'restart')
                check_response(r, member.name, 'flush scheduled restart', True)

        r = request_patroni(member, 'post', 'restart', content)
        if r.status == 200:
            click.echo('Success: restart on member {0}'.format(member.name))
        elif r.status == 202:
            click.echo('Success: restart scheduled on member {0}'.format(member.name))
        elif r.status == 409:
            click.echo('Failed: another restart is already scheduled on member {0}'.format(member.name))
        else:
            click.echo('Failed: restart for member {0}, status code={1}, ({2})'.format(
                member.name, r.status, r.data.decode('utf-8'))
            )
Process ``restart`` command of ``patronictl`` utility.

    Restart Postgres on cluster members based on given filters.

    :param cluster_name: name of the Patroni cluster.
    :param group: filter which Citus group we should restart members. Refer to the module note for more details.
    :param member_names: name of the members that should be restarted.
    :param force: perform the restart without asking for confirmations.
    :param role: role to filter members. See :func:`get_all_members` for available options.
    :param p_any: restart a single and random member among the ones that match the given filters.
    :param scheduled: timestamp when the restart should be scheduled to occur. If ``now`` restart immediately.
    :param version: restart only members which Postgres version is less than *version*.
    :param pending: restart only members that are flagged as ``pending restart``.
    :param timeout: timeout for the restart operation. If timeout is reached a failover may occur in the cluster.

    :raises:
        :class:`PatroniCtlException`: if:
            * *scheduled* could not be parsed; or
            * *version* could not be parsed; or
            * a restart is attempted against a cluster that is in maintenance mode.
    
patroni/ctl.py