129 lines
3.7 KiB
C++
129 lines
3.7 KiB
C++
// Copyright (c) Vitaliy Filippov, 2019+
|
|
// License: VNPL-1.1 (see README.md for details)
|
|
|
|
#include <algorithm>
|
|
#include "cli.h"
|
|
#include "cluster_client.h"
|
|
#include "str_util.h"
|
|
#include "json_util.h"
|
|
|
|
// List users
|
|
struct user_lister_t
|
|
{
|
|
cli_tool_t *parent;
|
|
std::vector<std::string> only_names;
|
|
|
|
int state = 0;
|
|
cli_result_t result;
|
|
json11::Json::array users;
|
|
|
|
bool is_done()
|
|
{
|
|
return state == 100;
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
if (state == 1)
|
|
goto resume_1;
|
|
if (state == 100)
|
|
return;
|
|
{
|
|
json11::Json::array select;
|
|
if (!only_names.size())
|
|
{
|
|
select.push_back(json11::Json::object {
|
|
{ "request_range", json11::Json::object {
|
|
{ "key", base64_encode(
|
|
parent->cli->st_cli.etcd_prefix+"/config/user/"
|
|
) },
|
|
{ "range_end", base64_encode(
|
|
parent->cli->st_cli.etcd_prefix+"/config/user0"
|
|
) },
|
|
} },
|
|
});
|
|
}
|
|
else
|
|
{
|
|
for (auto & name: only_names)
|
|
{
|
|
select.push_back(json11::Json::object {
|
|
{ "request_range", json11::Json::object {
|
|
{ "key", base64_encode(parent->cli->st_cli.etcd_prefix+"/config/user/"+name) },
|
|
} }
|
|
});
|
|
}
|
|
}
|
|
parent->etcd_txn(json11::Json::object {
|
|
{ "success", select },
|
|
});
|
|
}
|
|
state = 1;
|
|
resume_1:
|
|
if (parent->waiting > 0)
|
|
return;
|
|
if (parent->etcd_err.err)
|
|
{
|
|
result = parent->etcd_err;
|
|
state = 100;
|
|
return;
|
|
}
|
|
for (auto & response: parent->etcd_result["responses"].array_items())
|
|
{
|
|
for (auto & kv_item: response["response_range"]["kvs"].array_items())
|
|
{
|
|
auto kv = parent->cli->st_cli.parse_etcd_kv(kv_item);
|
|
auto user = kv.value.object_items();
|
|
user["name"] = kv.key.substr(parent->cli->st_cli.etcd_prefix.size()+13);
|
|
if (!parent->json_output)
|
|
user["groups_fmt"] = implode(",", user["groups"].array_items());
|
|
users.push_back(std::move(user));
|
|
}
|
|
}
|
|
if (parent->json_output)
|
|
{
|
|
// JSON output
|
|
result.data = users;
|
|
state = 100;
|
|
return;
|
|
}
|
|
// Table output: name, type, groups
|
|
json11::Json::array cols;
|
|
cols.push_back(json11::Json::object{
|
|
{ "key", "name" },
|
|
{ "title", "NAME" },
|
|
});
|
|
cols.push_back(json11::Json::object{
|
|
{ "key", "type" },
|
|
{ "title", "TYPE" },
|
|
});
|
|
cols.push_back(json11::Json::object{
|
|
{ "key", "groups_fmt" },
|
|
{ "title", "GROUPS" },
|
|
});
|
|
result.text = print_table(users, cols, parent->color);
|
|
state = 100;
|
|
}
|
|
};
|
|
|
|
std::function<bool(cli_result_t &)> cli_tool_t::start_user_ls(json11::Json cfg)
|
|
{
|
|
auto lister = new user_lister_t();
|
|
lister->parent = this;
|
|
if (cfg["names"].is_string())
|
|
lister->only_names.push_back(cfg["names"].string_value());
|
|
for (auto & item: cfg["names"].array_items())
|
|
lister->only_names.push_back(item.string_value());
|
|
return [lister](cli_result_t & result)
|
|
{
|
|
lister->loop();
|
|
if (lister->is_done())
|
|
{
|
|
result = lister->result;
|
|
delete lister;
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
}
|