mirror of
https://github.com/OpenNebula/one.git
synced 2026-10-25 20:57:40 +09:00
274 lines
8.4 KiB
C++
274 lines
8.4 KiB
C++
/* -------------------------------------------------------------------------- */
|
|
/* 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<int>& 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<int> _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 <typename T>
|
|
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 <typename T>
|
|
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 <typename T>
|
|
void make_parameter(std::ostringstream& oss, int pos, const T& val)
|
|
{
|
|
oss << "<PARAMETER>"
|
|
<< "<POSITION>" << pos << "</POSITION>"
|
|
<< "<TYPE>OUT</TYPE>"
|
|
<< "<VALUE>" << val << "</VALUE>"
|
|
<< "</PARAMETER>";
|
|
}
|
|
|
|
/* Compose xml output, used for hooks */
|
|
template <typename T>
|
|
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<T, bool>)
|
|
{
|
|
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_
|
|
|