| /** |
| @section license License |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| #pragma once |
| |
| #include <iostream> |
| |
| #include "tscore/ArgParser.h" |
| |
| #include "shared/rpc/RPCClient.h" |
| #include "CtrlPrinters.h" |
| |
| /// @brief Class that provides access to the RPC side of things. |
| struct RPCAccessor { |
| protected: |
| /// @brief Invoke the remote server. This is the very basic function which does not play or interact with any codec. Request |
| /// and message should be already en|de coded. |
| /// @param request A string representation of the json/yaml request. |
| /// @return a string with the json/yaml response. |
| /// @note This function does print the raw string if requested by the "--format". No printer involved, standard output. |
| std::string invoke_rpc(std::string const &request, std::chrono::milliseconds timeout_ms, int attempts); |
| |
| /// @brief Function that calls the rpc server. This function takes a json objects and uses the defined coded to convert them to a |
| /// string. This function will call invoke_rpc(string) overload. |
| /// @param A Client request. |
| /// @return A server response. |
| shared::rpc::JSONRPCResponse invoke_rpc(shared::rpc::ClientRequest const &request, std::chrono::milliseconds timeout_ms, |
| int attempts); |
| |
| /// @brief Function that calls the rpc server. The response will not be decoded, it will be a raw string. |
| void invoke_rpc(shared::rpc::ClientRequest const &request, std::string &bw, std::chrono::milliseconds timeout_ms, int attempts); |
| |
| std::unique_ptr<BasePrinter> _printer; //!< Specific output formatter. This should be created by the derived class. |
| private: |
| shared::rpc::RPCClient _rpcClient; //!< RPC socket client implementation. |
| }; |
| |
| // ---------------------------------------------------------------------------------------------------------------------------------- |
| /// |
| /// @brief Base Control Command class. |
| /// This class should be used as a base class for every new command or group of commands that are related. |
| /// The base class will provide the client communication through the @c invoke_call member function. Arguments that were |
| /// parsed by the traffic_ctl are available as a member to all the derived classes. |
| class CtrlCommand : public RPCAccessor |
| { |
| public: |
| virtual ~CtrlCommand() = default; |
| |
| /// @brief This object will hold the arguments for now. |
| /// @note If you don't need to handle the args in your derived class you should just inherit CtrlCommand ctor: |
| /// 'using CtrlCommand::CtrlCommand;' |
| CtrlCommand(ts::Arguments *args); |
| |
| /// @brief Main execution point for a particular command. This function will invoke @c _invoked_func which should be set |
| /// by the derived class. In case you do not want the @c _invoked_func to be called directly, you should override this |
| /// member function and call it yourself. |
| /// If @c _invoked_func is not properly set, the function will throw @c logic_error |
| virtual void execute(); |
| |
| /// @brief This variable is used to mark if a Signal was flagged by the application. Default value is 0 and the signal number |
| /// should be set when the signal is handled. |
| static std::atomic_int Signal_Flagged; |
| |
| std::string invoke_rpc(std::string const &request); |
| |
| shared::rpc::JSONRPCResponse invoke_rpc(shared::rpc::ClientRequest const &request); |
| |
| protected: |
| /// @brief The whole design is that the command will execute the @c _invoked_func once invoked. This function ptr should be |
| /// set by the appropriated derived class base on the passed parameters. The derived class have the option to override |
| /// the execute() function and do something else. Check @c RecordCommand as an example. |
| std::function<void(void)> _invoked_func; //!< Actual function that the command will execute. |
| |
| /// @brief Return the parsed arguments. |
| ts::Arguments * |
| get_parsed_arguments() |
| { |
| return _arguments; |
| } |
| |
| private: |
| ts::Arguments *_arguments = nullptr; //!< parsed traffic_ctl arguments. |
| }; |
| |
| // ----------------------------------------------------------------------------------------------------------------------------------- |
| /// |
| /// @brief Record Command Implementation |
| /// Used as base class for any command that needs to access to a TS record. |
| /// If deriving from this class, make sure you implement @c execute_subcommand() and call the _invoked_func yourself. |
| class RecordCommand : public CtrlCommand |
| { |
| public: |
| using CtrlCommand::CtrlCommand; |
| virtual ~RecordCommand() = default; |
| |
| protected: |
| static inline const std::string MATCH_STR{"match"}; |
| static inline const std::string GET_STR{"get"}; |
| static inline const std::string DESCRIBE_STR{"describe"}; |
| |
| /// @brief Handy enum to hold which kind of records we are requesting. |
| enum class RecordQueryType { CONFIG = 0, METRIC }; |
| /// @brief Function to fetch record from the rpc server. |
| /// @param argData argument's data. |
| /// @param isRegex if the request should be done by regex or name. |
| /// @param recQueryType Config or Metric. |
| shared::rpc::JSONRPCResponse record_fetch(ts::ArgumentData argData, bool isRegex, RecordQueryType recQueryType); |
| }; |
| // ----------------------------------------------------------------------------------------------------------------------------------- |
| class ConfigCommand : public RecordCommand |
| { |
| static inline const std::string DIFF_STR{"diff"}; |
| static inline const std::string DEFAULTS_STR{"defaults"}; |
| static inline const std::string SET_STR{"set"}; |
| static inline const std::string COLD_STR{"cold"}; |
| static inline const std::string APPEND_STR{"append"}; |
| static inline const std::string STATUS_STR{"status"}; |
| static inline const std::string RELOAD_STR{"reload"}; |
| static inline const std::string REGISTRY_STR{"registry"}; |
| |
| void config_match(); |
| void config_get(); |
| void config_describe(); |
| void config_defaults(); |
| void config_diff(); |
| void config_status(); |
| void config_set(); |
| void file_config_set(); |
| void config_reload(); |
| void config_show_file_registry(); |
| |
| public: |
| ConfigCommand(ts::Arguments *args); |
| }; |
| // ----------------------------------------------------------------------------------------------------------------------------------- |
| class MetricCommand : public RecordCommand |
| { |
| static inline const std::string MONITOR_STR{"monitor"}; |
| |
| void metric_get(); |
| void metric_match(); |
| void metric_describe(); |
| void metric_monitor(); |
| |
| public: |
| MetricCommand(ts::Arguments *args); |
| }; |
| // ----------------------------------------------------------------------------------------------------------------------------------- |
| class HostCommand : public CtrlCommand |
| { |
| public: |
| HostCommand(ts::Arguments *args); |
| |
| private: |
| static inline const std::string STATUS_STR{"status"}; |
| static inline const std::string DOWN_STR{"down"}; |
| static inline const std::string UP_STR{"up"}; |
| static inline const std::string REASON_STR{"reason"}; |
| |
| void status_get(); |
| void status_down(); |
| void status_up(); |
| }; |
| // ----------------------------------------------------------------------------------------------------------------------------------- |
| class HostDBCommand : public CtrlCommand |
| { |
| public: |
| HostDBCommand(ts::Arguments *args); |
| |
| private: |
| static inline const std::string STATUS_STR{"status"}; |
| |
| void status_get(); |
| }; |
| // ----------------------------------------------------------------------------------------------------------------------------------- |
| class PluginCommand : public CtrlCommand |
| { |
| public: |
| PluginCommand(ts::Arguments *args); |
| |
| private: |
| static inline const std::string MSG_STR{"msg"}; |
| void plugin_msg(); |
| }; |
| // ----------------------------------------------------------------------------------------------------------------------------------- |
| class DirectRPCCommand : public CtrlCommand |
| { |
| public: |
| DirectRPCCommand(ts::Arguments *args); |
| |
| private: |
| static inline const std::string GET_API_STR{"get-api"}; |
| static inline const std::string FILE_STR{"file"}; |
| static inline const std::string INPUT_STR{"input"}; |
| static inline const std::string INVOKE_STR{"invoke"}; |
| static inline const std::string RAW_STR{"raw"}; |
| static inline const std::string PARAMS_STR{"params"}; |
| |
| void from_file_request(); |
| void get_rpc_api(); |
| void read_from_input(); |
| void invoke_method(); |
| /// run a YAML validation on the input. |
| bool validate_input(std::string const &in) const; |
| }; |
| // ----------------------------------------------------------------------------------------------------------------------------------- |
| class ServerCommand : public CtrlCommand |
| { |
| public: |
| ServerCommand(ts::Arguments *args); |
| |
| private: |
| static inline const std::string DRAIN_STR{"drain"}; |
| static inline const std::string UNDO_STR{"undo"}; |
| static inline const std::string NO_NEW_CONN_STR{"no-new-connection"}; |
| |
| static inline const std::string DEBUG_STR{"debug"}; |
| static inline const std::string ENABLE_STR{"enable"}; |
| static inline const std::string DISABLE_STR{"disable"}; |
| static inline const std::string TAGS_STR{"tags"}; |
| static inline const std::string CLIENT_IP_STR{"client_ip"}; |
| |
| static inline const std::string STATUS_STR{"status"}; |
| |
| void server_drain(); |
| void server_debug(); |
| void server_status(); |
| }; |
| // |
| // ----------------------------------------------------------------------------------------------------------------------------------- |
| struct StorageCommand : public CtrlCommand { |
| StorageCommand(ts::Arguments *args); |
| |
| private: |
| static inline const std::string STATUS_STR{"status"}; |
| static inline const std::string OFFLINE_STR{"offline"}; |
| |
| void get_storage_status(); |
| void set_storage_offline(); |
| }; |
| // ----------------------------------------------------------------------------------------------------------------------------------- |
| |
| BasePrinter::Options::FormatFlags parse_print_opts(ts::Arguments *args); |