[ui] Implement provider test button #49
This commit is contained in:
@ -49,6 +49,7 @@ static const option password_option = {"-pw", "--password"};
|
||||
static const option remote_mount_option = {"-rm", "--remote_mount"};
|
||||
static const option set_option = {"-set", "--set"};
|
||||
static const option status_option = {"-status", "--status"};
|
||||
static const option test_option = {"-test", "--test"};
|
||||
static const option ui_option = {"-ui", "--ui"};
|
||||
static const option ui_port_option = {"-up", "--ui_port"};
|
||||
static const option unmount_option = {"-unmount", "--unmount"};
|
||||
@ -77,6 +78,7 @@ static const std::vector<option> option_list = {
|
||||
remote_mount_option,
|
||||
set_option,
|
||||
status_option,
|
||||
test_option,
|
||||
ui_option,
|
||||
ui_port_option,
|
||||
unmount_option,
|
||||
|
@ -793,8 +793,22 @@ auto s3_provider::is_file(const std::string &api_path, bool &exists) const
|
||||
}
|
||||
|
||||
auto s3_provider::is_online() const -> bool {
|
||||
// TODO implement this
|
||||
return true;
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
|
||||
try {
|
||||
bool is_encrypted{};
|
||||
std::string object_name;
|
||||
head_object_result result{};
|
||||
auto res{
|
||||
get_object_info(true, "/", is_encrypted, object_name, result),
|
||||
};
|
||||
|
||||
return res == api_error::success;
|
||||
} catch (const std::exception &e) {
|
||||
utils::error::raise_error(function_name, e, "exception occurred");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto s3_provider::read_file_bytes(const std::string &api_path, std::size_t size,
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "cli/pinned_status.hpp"
|
||||
#include "cli/set.hpp"
|
||||
#include "cli/status.hpp"
|
||||
#include "cli/test.hpp"
|
||||
#include "cli/ui.hpp"
|
||||
#include "cli/unmount.hpp"
|
||||
#include "cli/unpin_file.hpp"
|
||||
@ -48,7 +49,7 @@ using action = std::function<exit_code(
|
||||
|
||||
struct option_hasher {
|
||||
auto operator()(const utils::cli::option &opt) const -> std::size_t {
|
||||
return std::hash<std::string>()(opt[0U] + '|' + opt[1U]);
|
||||
return std::hash<std::string>()(opt.at(0U) + '|' + opt.at(1U));
|
||||
}
|
||||
};
|
||||
|
||||
@ -71,6 +72,7 @@ static const std::unordered_map<utils::cli::option, action, option_hasher>
|
||||
cli::actions::pinned_status},
|
||||
{utils::cli::options::set_option, cli::actions::set},
|
||||
{utils::cli::options::status_option, cli::actions::status},
|
||||
{utils::cli::options::test_option, cli::actions::test},
|
||||
{utils::cli::options::ui_option, cli::actions::ui},
|
||||
{utils::cli::options::unmount_option, cli::actions::unmount},
|
||||
{utils::cli::options::unpin_file_option, cli::actions::unpin_file},
|
||||
|
@ -44,12 +44,12 @@ namespace repertory::cli::actions {
|
||||
std::string required_version;
|
||||
std::string returned_version;
|
||||
if (provider.check_version(required_version, returned_version)) {
|
||||
fmt::println("Success:\n\tRequired: {}\n\tActual: {}", required_version,
|
||||
fmt::println("0\nSuccess:\n\tRequired: {}\n\tActual: {}", required_version,
|
||||
returned_version);
|
||||
return exit_code::success;
|
||||
}
|
||||
|
||||
fmt::println("Failed:\n\tRequired: {}\n\tActual: {}", required_version,
|
||||
fmt::println("1\nFailed:\n\tRequired: {}\n\tActual: {}", required_version,
|
||||
returned_version);
|
||||
return exit_code::incompatible_version;
|
||||
}
|
||||
|
45
repertory/repertory/include/cli/test.hpp
Normal file
45
repertory/repertory/include/cli/test.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
Copyright <2018-2025> <scott.e.graves@protonmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#ifndef REPERTORY_INCLUDE_CLI_TEST_HPP_
|
||||
#define REPERTORY_INCLUDE_CLI_TEST_HPP_
|
||||
|
||||
#include "cli/common.hpp"
|
||||
|
||||
namespace repertory::cli::actions {
|
||||
[[nodiscard]] inline auto
|
||||
test(std::vector<const char *> /* args */, const std::string &data_directory,
|
||||
const provider_type &prov, const std::string & /*unique_id*/,
|
||||
std::string /*user*/, std::string /*password*/) -> exit_code {
|
||||
app_config config(prov, data_directory);
|
||||
if (prov == provider_type::remote) {
|
||||
return exit_code::exception;
|
||||
}
|
||||
|
||||
auto provider{create_provider(prov, config)};
|
||||
auto is_online{provider->is_online()};
|
||||
fmt::println("{}\nProvider is {}!", utils::string::from_bool(is_online),
|
||||
is_online ? "online" : "offline");
|
||||
return is_online ? exit_code::success : exit_code::exception;
|
||||
}
|
||||
} // namespace repertory::cli::actions
|
||||
|
||||
#endif // REPERTORY_INCLUDE_CLI_TEST_HPP_
|
@ -69,11 +69,16 @@ private:
|
||||
std::condition_variable nonce_notify_;
|
||||
std::unique_ptr<std::thread> nonce_thread_;
|
||||
stop_type stop_requested{false};
|
||||
mutable std::mutex test_mtx_;
|
||||
|
||||
private:
|
||||
[[nodiscard]] auto data_directory_exists(provider_type prov,
|
||||
std::string_view name) const -> bool;
|
||||
|
||||
void
|
||||
generate_config(provider_type prov, std::string_view name, const json &cfg,
|
||||
std::optional<std::string> data_dir = std::nullopt) const;
|
||||
|
||||
static void handle_get_available_locations(httplib::Response &res);
|
||||
|
||||
void handle_get_mount(const httplib::Request &req,
|
||||
@ -91,6 +96,9 @@ private:
|
||||
|
||||
void handle_get_settings(httplib::Response &res) const;
|
||||
|
||||
void handle_get_test(const httplib::Request &req,
|
||||
httplib::Response &res) const;
|
||||
|
||||
void handle_post_add_mount(const httplib::Request &req,
|
||||
httplib::Response &res) const;
|
||||
|
||||
@ -113,7 +121,8 @@ private:
|
||||
void removed_expired_nonces();
|
||||
|
||||
void set_key_value(provider_type prov, std::string_view name,
|
||||
std::string_view key, std::string_view value) const;
|
||||
std::string_view key, std::string_view value,
|
||||
std::optional<std::string> data_dir = std::nullopt) const;
|
||||
};
|
||||
} // namespace repertory::ui
|
||||
|
||||
|
@ -98,6 +98,7 @@ namespace {
|
||||
|
||||
return std::string{value};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace repertory::ui {
|
||||
@ -200,6 +201,9 @@ handlers::handlers(mgmt_app_config *config, httplib::Server *server)
|
||||
handle_get_settings(res);
|
||||
});
|
||||
|
||||
server->Get("/api/v1/test",
|
||||
[this](auto &&req, auto &&res) { handle_get_test(req, res); });
|
||||
|
||||
server->Post("/api/v1/add_mount", [this](auto &&req, auto &&res) {
|
||||
handle_post_add_mount(req, res);
|
||||
});
|
||||
@ -308,6 +312,46 @@ auto handlers::data_directory_exists(provider_type prov,
|
||||
return ret;
|
||||
}
|
||||
|
||||
void handlers::generate_config(provider_type prov, std::string_view name,
|
||||
const json &cfg,
|
||||
std::optional<std::string> data_dir) const {
|
||||
std::map<std::string, std::string> values{};
|
||||
for (const auto &[key, value] : cfg.items()) {
|
||||
if (value.is_object()) {
|
||||
for (const auto &[key2, value2] : value.items()) {
|
||||
auto sub_key = fmt::format("{}.{}", key, key2);
|
||||
auto skip{false};
|
||||
auto decrypted = decrypt_value(
|
||||
config_, sub_key, value2.template get<std::string>(), skip);
|
||||
if (skip) {
|
||||
continue;
|
||||
}
|
||||
values[sub_key] = decrypted;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
auto skip{false};
|
||||
auto decrypted =
|
||||
decrypt_value(config_, key, value.template get<std::string>(), skip);
|
||||
if (skip) {
|
||||
continue;
|
||||
}
|
||||
values[key] = decrypted;
|
||||
}
|
||||
|
||||
if (data_dir.has_value()) {
|
||||
launch_process(prov, name, {"-dd", data_dir.value(), "-gc"});
|
||||
} else {
|
||||
launch_process(prov, name, {"-gc"});
|
||||
}
|
||||
|
||||
for (const auto &[key, value] : values) {
|
||||
set_key_value(prov, name, key, value, data_dir);
|
||||
}
|
||||
}
|
||||
|
||||
void handlers::handle_put_mount_location(const httplib::Request &req,
|
||||
httplib::Response &res) const {
|
||||
REPERTORY_USES_FUNCTION_NAME();
|
||||
@ -367,7 +411,6 @@ void handlers::handle_get_mount(const httplib::Request &req,
|
||||
}
|
||||
|
||||
auto lines = launch_process(prov, name, {"-dc"});
|
||||
|
||||
if (lines.at(0U) != "0") {
|
||||
throw utils::error::create_exception(function_name, {
|
||||
"command failed",
|
||||
@ -475,6 +518,26 @@ void handlers::handle_get_settings(httplib::Response &res) const {
|
||||
res.status = http_error_codes::ok;
|
||||
}
|
||||
|
||||
void handlers::handle_get_test(const httplib::Request &req,
|
||||
httplib::Response &res) const {
|
||||
unique_mutex_lock lock(test_mtx_);
|
||||
|
||||
auto name = req.get_param_value("name");
|
||||
auto prov = provider_type_from_string(req.get_param_value("type"));
|
||||
auto cfg = nlohmann::json::parse(req.get_param_value("config"));
|
||||
|
||||
auto data_dir = utils::path::combine(
|
||||
utils::directory::temp(), {utils::file::create_temp_name("repertory")});
|
||||
|
||||
generate_config(prov, name, cfg, data_dir);
|
||||
|
||||
auto lines = launch_process(prov, name, {"-dd", data_dir, "-test"});
|
||||
res.status = lines.at(0U) == "0" ? http_error_codes::ok
|
||||
: http_error_codes::internal_error;
|
||||
|
||||
utils::file::directory{data_dir}.remove_recursively();
|
||||
}
|
||||
|
||||
void handlers::handle_post_add_mount(const httplib::Request &req,
|
||||
httplib::Response &res) const {
|
||||
auto name = req.get_param_value("name");
|
||||
@ -485,38 +548,9 @@ void handlers::handle_post_add_mount(const httplib::Request &req,
|
||||
}
|
||||
|
||||
auto cfg = nlohmann::json::parse(req.get_param_value("config"));
|
||||
generate_config(prov, name, cfg);
|
||||
|
||||
std::map<std::string, std::string> values{};
|
||||
for (const auto &[key, value] : cfg.items()) {
|
||||
if (value.is_object()) {
|
||||
for (const auto &[key2, value2] : value.items()) {
|
||||
auto sub_key = fmt::format("{}.{}", key, key2);
|
||||
auto skip{false};
|
||||
auto decrypted = decrypt_value(
|
||||
config_, sub_key, value2.template get<std::string>(), skip);
|
||||
if (skip) {
|
||||
continue;
|
||||
}
|
||||
values[sub_key] = decrypted;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
auto skip{false};
|
||||
auto decrypted =
|
||||
decrypt_value(config_, key, value.template get<std::string>(), skip);
|
||||
if (skip) {
|
||||
continue;
|
||||
}
|
||||
values[key] = decrypted;
|
||||
}
|
||||
|
||||
launch_process(prov, name, {"-gc"});
|
||||
for (auto &[key, value] : values) {
|
||||
set_key_value(prov, name, key, value);
|
||||
}
|
||||
|
||||
launch_process(prov, name, {"-test"});
|
||||
res.status = http_error_codes::ok;
|
||||
}
|
||||
|
||||
@ -743,9 +777,13 @@ void handlers::removed_expired_nonces() {
|
||||
}
|
||||
|
||||
void handlers::set_key_value(provider_type prov, std::string_view name,
|
||||
std::string_view key,
|
||||
std::string_view value) const {
|
||||
std::string_view key, std::string_view value,
|
||||
std::optional<std::string> data_dir) const {
|
||||
std::vector<std::string> args;
|
||||
if (data_dir.has_value()) {
|
||||
args.emplace_back("-dd");
|
||||
args.emplace_back(data_dir.value());
|
||||
}
|
||||
args.emplace_back("-set");
|
||||
args.emplace_back(key);
|
||||
args.emplace_back(value);
|
||||
|
Reference in New Issue
Block a user