**Describe the unexpected behaviour**
ClickHouse Keeper reached consensus and chose the leader with incorrect configuration:
``` yaml
raft_configuration:
          server:
            - id: 0
              hostname: keeper-0
              port: 44444
            - id: 1
              hostname: keeper-0
              port: 44444
            - id: 2
              hostname: keeper-0
              port: 44444
```
Nodes had different ids to achieve this.
 
**Expected behavior**
Add sanity checks for raft config:
- No duplicate keeper nodes 
- No duplicate ids

We can 
1) Fail if keeper/server starts with such configuration
2) We should not allow to commit this configuration to log even if bad node proposed such change.
#include <Coordination/KeeperStateManager.h>
#include <Coordination/Defines.h>
#include <Common/Exception.h>
#include <filesystem>
namespace DB
{
namespace ErrorCodes
{
    extern const int RAFT_ERROR;
}
KeeperStateManager::KeeperConfigurationWrapper KeeperStateManager::parseServersConfiguration(const Poco::Util::AbstractConfiguration & config, bool allow_without_us) const
{
    KeeperConfigurationWrapper result;
    result.cluster_config = std::make_shared<nuraft::cluster_config>();
    Poco::Util::AbstractConfiguration::Keys keys;
    config.keys(config_prefix + ".raft_configuration", keys);
    size_t total_servers = 0;
    for (const auto & server_key : keys)
    {
        if (!startsWith(server_key, "server"))
            continue;
        std::string full_prefix = config_prefix + ".raft_configuration." + server_key;
        int new_server_id = config.getInt(full_prefix + ".id");
        std::string hostname = config.getString(full_prefix + ".hostname");
        int port = config.getInt(full_prefix + ".port");
        bool can_become_leader = config.getBool(full_prefix + ".can_become_leader", true);
        int32_t priority = config.getInt(full_prefix + ".priority", 1);
        bool start_as_follower = config.getBool(full_prefix + ".start_as_follower", false);