Skip to content

Commit

Permalink
Add CLI support
Browse files Browse the repository at this point in the history
  • Loading branch information
namchuai committed Nov 18, 2024
1 parent e95ca37 commit cc1313d
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 29 deletions.
35 changes: 15 additions & 20 deletions engine/cli/command_line_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -326,14 +326,8 @@ void CommandLineParser::SetupModelCommands() {
void CommandLineParser::SetupConfigsCommands() {
auto config_cmd =
app_.add_subcommand("config", "Subcommands for managing configurations");
config_cmd->usage(
"Usage:\n" + commands::GetCortexBinary() +
" config status for listing all API server configuration.\n" +
commands::GetCortexBinary() +
" config --cors [on/off] to toggle CORS.\n" +
commands::GetCortexBinary() +
" config --allowed_origins [comma separated origin] to set a list of "
"allowed origin");
config_cmd->usage("Usage:\n" + commands::GetCortexBinary() +
" config [option] [value]");
config_cmd->group(kConfigGroup);
auto config_status_cmd =
config_cmd->add_subcommand("status", "Print all configurations");
Expand All @@ -344,18 +338,19 @@ void CommandLineParser::SetupConfigsCommands() {
std::stoi(cml_data_.config.apiServerPort));
});

// TODO: this can be improved
std::vector<std::string> avai_opts{"cors", "allowed_origins"};
std::unordered_map<std::string, std::string> description{
{"cors", "[on/off] Toggling CORS."},
{"allowed_origins",
"Allowed origins for CORS. Comma separated. E.g. "
"http://localhost,https://cortex.so"}};
for (const auto& opt : avai_opts) {
std::string option = "--" + opt;
config_cmd->add_option(option, config_update_opts_[opt], description[opt])
->expected(0, 1)
->default_str("*");
// TODO: recheck the allowed_origins to be able to set to empty
for (const auto& [key, opt] : CONFIGURATIONS) {
std::string option = "--" + opt.name;
auto option_cmd =
config_cmd->add_option(option, config_update_opts_[opt.name], opt.desc)
->group(opt.group)
->default_str(opt.default_value);

if (opt.allow_empty) {
option_cmd->expected(0, 1);
} else {
option_cmd->expected(1);
}
}

config_cmd->callback([this, config_cmd] {
Expand Down
30 changes: 21 additions & 9 deletions engine/cli/commands/config_upd_cmd.cc
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
#include "config_upd_cmd.h"
#include "commands/server_start_cmd.h"
#include "common/api_server_configuration.h"
#include "utils/curl_utils.h"
#include "utils/logging_utils.h"
#include "utils/string_utils.h"
#include "utils/url_parser.h"

namespace {
const std::vector<std::string> config_keys{"cors", "allowed_origins"};

inline Json::Value NormalizeJson(
const std::unordered_map<std::string, std::string> options) {
Json::Value root;
for (const auto& [key, value] : options) {
if (std::find(config_keys.begin(), config_keys.end(), key) ==
config_keys.end()) {
if (CONFIGURATIONS.find(key) == CONFIGURATIONS.end()) {
continue;
}
auto config = CONFIGURATIONS.at(key);

if (key == "cors") {
if (config.accept_value == "[on|off]") {
if (string_utils::EqualsIgnoreCase("on", value)) {
root["cors"] = true;
root[key] = true;
} else if (string_utils::EqualsIgnoreCase("off", value)) {
root["cors"] = false;
root[key] = false;
}
} else if (key == "allowed_origins") {
} else if (config.accept_value == "comma separated") {
auto origins = string_utils::SplitBy(value, ",");
Json::Value origin_array(Json::arrayValue);
for (const auto& origin : origins) {
origin_array.append(origin);
}
root[key] = origin_array;
} else if (config.accept_value == "string") {
root[key] = value;
} else {
CTL_ERR("Not support configuration type: " << config.accept_value
<< " for config key: " << key);
}
}

Expand All @@ -50,13 +54,21 @@ void commands::ConfigUpdCmd::Exec(
}
}

auto non_null_opts = std::unordered_map<std::string, std::string>();
for (const auto& [key, value] : options) {
if (value.empty()) {
continue;
}
non_null_opts[key] = value;
}

auto url = url_parser::Url{
.protocol = "http",
.host = host + ":" + std::to_string(port),
.pathParams = {"v1", "configs"},
};

auto json = NormalizeJson(options);
auto json = NormalizeJson(non_null_opts);
if (json.empty()) {
CLI_LOG_ERROR("Invalid configuration options provided");
return;
Expand Down
72 changes: 72 additions & 0 deletions engine/common/api_server_configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,78 @@ enum class ProxyAuthMethod {
AwsSigV4
};

struct ApiConfigurationMetadata {
std::string name;
std::string desc;
std::string group;
std::string accept_value;
std::string default_value;

bool allow_empty = false;
};

static const std::unordered_map<std::string, ApiConfigurationMetadata>
CONFIGURATIONS = {
{"cors",
ApiConfigurationMetadata{
.name = "cors",
.desc = "Cross-Origin Resource Sharing configuration.",
.group = "CORS",
.accept_value = "[on|off]",
.default_value = "on"}},
{"allowed_origins",
ApiConfigurationMetadata{
.name = "allowed_origins",
.desc = "Allowed origins for CORS. Comma separated. E.g. "
"http://localhost,https://cortex.so",
.group = "CORS",
.accept_value = "comma separated",
.default_value = "*",
.allow_empty = true}},
{"proxy_url", ApiConfigurationMetadata{.name = "proxy_url",
.desc = "Proxy URL",
.group = "Proxy",
.accept_value = "string",
.default_value = ""}},
{"proxy_username", ApiConfigurationMetadata{.name = "proxy_username",
.desc = "Proxy Username",
.group = "Proxy",
.accept_value = "string",
.default_value = ""}},
{"proxy_password", ApiConfigurationMetadata{.name = "proxy_password",
.desc = "Proxy Password",
.group = "Proxy",
.accept_value = "string",
.default_value = ""}},
{"verify_proxy_ssl",
ApiConfigurationMetadata{.name = "verify_proxy_ssl",
.desc = "Verify SSL for proxy",
.group = "Proxy",
.accept_value = "[on|off]",
.default_value = "on"}},
{"verify_proxy_host_ssl",
ApiConfigurationMetadata{.name = "verify_proxy_host_ssl",
.desc = "Verify SSL for proxy",
.group = "Proxy",
.accept_value = "[on|off]",
.default_value = "on"}},
{"no_proxy", ApiConfigurationMetadata{.name = "no_proxy",
.desc = "No proxy for hosts",
.group = "Proxy",
.accept_value = "string",
.default_value = ""}},
{"verify_peer_ssl", ApiConfigurationMetadata{.name = "verify_peer_ssl",
.desc = "Verify peer SSL",
.group = "Proxy",
.accept_value = "[on|off]",
.default_value = "on"}},
{"verify_host_ssl", ApiConfigurationMetadata{.name = "verify_host_ssl",
.desc = "Verify host SSL",
.group = "Proxy",
.accept_value = "[on|off]",
.default_value = "on"}},
};

class ApiServerConfiguration {
public:
ApiServerConfiguration(
Expand Down

0 comments on commit cc1313d

Please sign in to comment.