/* -------------------------------------------------------------------------- */ /* Copyright 2002-2026, OpenNebula Project, OpenNebula Systems */ /* */ /* Licensed 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. */ /* -------------------------------------------------------------------------- */ #ifndef REQUEST_H_ #define REQUEST_H_ #include "AuthRequest.h" #include "Quotas.h" #include "UserPool.h" #include "PoolObjectSQL.h" #include "RequestAttributes.h" #include "HookAPI.h" /** * The Request Class represents the basic abstraction for the OpenNebula * XML-RPC API. This interface must be implemented by any XML-RPC API call */ class Request { public: /** * Error codes for the OpenNebula API */ enum ErrorCode { SUCCESS = 0x00000, AUTHENTICATION = 0x00100, AUTHORIZATION = 0x00200, NO_EXISTS = 0x00400, ACTION = 0x00800, RPC_API = 0x01000, INTERNAL = 0x02000, ALLOCATE = 0x04000, LOCKED = 0x08000, REPLICATION = 0x10000 }; /* ---------------------------------------------------------------------- */ /* Class Constructors */ /* ---------------------------------------------------------------------- */ Request(const std::string& mn): _method_name(mn), _log_method_call(true), _leader_only(true), _zone_disabled(false) {} virtual ~Request() = default; /** * A descriptive error message is constructed using att.resp_obj, att.resp_id * and/or att.resp_msg and the ErrorCode * * @param ec error code for this call * @param ra the specific request attributes */ static std::string failure_message(ErrorCode ec, RequestAttributes& att, const std::string& method_name, PoolObjectSQL::ObjectType auth_object = PoolObjectSQL::NONE); /* ---------------------------------------------------------------------- */ /* Request Attributes */ /* ---------------------------------------------------------------------- */ const std::string& method_name() const { return _method_name; } void method_name(const std::string& mn) { _method_name = mn; } PoolObjectSQL::ObjectType auth_object() const { return _auth_object; } void auth_object(PoolObjectSQL::ObjectType ao) { _auth_object = ao; } void auth_op(AuthRequest::Operation ao) { _auth_op = ao; } void hidden_params(const std::set& hp) { _hidden_params = hp; _hidden_params.insert(0); // always hide the first parameter } void leader_only(bool lo) { _leader_only = lo; } void log_method_call(bool lm) { _log_method_call = lm; } void zone_disabled(bool zd) { _zone_disabled = zd; } protected: /* ---------------------------------------------------------------------- */ /* Global configuration attributes for API calls */ /* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ /* Request Attributes: shared among request of the same method */ /* ---------------------------------------------------------------------- */ std::string _method_name; // Configuration for authentication level of the API call PoolObjectSQL::ObjectType _auth_object = PoolObjectSQL::ObjectType::NONE; AuthRequest::Operation _auth_op = AuthRequest::NONE; // Logging configuration fot the API call std::set _hidden_params = { 0 }; // hide first parameter by default bool _log_method_call; // Method can be only execute by leaders or solo servers bool _leader_only; // Method can be executed in disabled state bool _zone_disabled; /* ---------------------------------------------------------------------- */ template void response(ErrorCode ec, const T& out, RequestAttributes& att) { if (ec == SUCCESS) { success_response(out, att); } else { failure_response(ec, att); } } /* ---------------------------------------------------------------------- */ /* Exit code functions for RPCs */ /* Prepares request exit code. After calling these functions the excute */ /* method should return */ /* ---------------------------------------------------------------------- */ void failure_response(ErrorCode ec, RequestAttributes& att); void failure_response(ErrorCode ec, const std::string& val, RequestAttributes& att) { if (HookAPI::supported_call(_method_name)) { make_xml_response(ec, val, att); } att.success = false; make_response(ec, val, att); } /** * @param val to be returned to the client * @param att the specific request attributes */ template void success_response(const T& val, RequestAttributes& att) { if (HookAPI::supported_call(_method_name)) { make_xml_response(SUCCESS, val, att); } att.success = true; make_response(SUCCESS, val, att); } /* Generate the protocol specific response message*/ virtual void make_response(ErrorCode ec, const std::string& value, RequestAttributes& att) {} virtual void make_response(ErrorCode ec, int value, RequestAttributes& att) {} virtual void make_response(ErrorCode ec, uint64_t value, RequestAttributes& att) {} /* ---------------------------------------------------------------------- */ template void make_parameter(std::ostringstream& oss, int pos, const T& val) { oss << "" << "" << pos << "" << "OUT" << "" << val << "" << ""; } /* Compose xml output, used for hooks */ template void make_xml_response(ErrorCode ec, const T& value, RequestAttributes& att) { std::ostringstream oss; if ( ec == SUCCESS ) { make_parameter(oss, 1, "true"); } else { make_parameter(oss, 1, "false"); } if constexpr (std::is_same_v) { make_parameter(oss, 2, value? "true": "false"); } else { make_parameter(oss, 2, value); } make_parameter(oss, 3, ec); if ( ec != SUCCESS ) { make_parameter(oss, 4, att.resp_id); } att.retval_xml = oss.str(); } }; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ #endif //REQUEST_H_