diff --git a/include/Request.h b/include/Request.h new file mode 100644 index 0000000000..4aad0e00ff --- /dev/null +++ b/include/Request.h @@ -0,0 +1,145 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* 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 +#include + +#include "RequestManager.h" + +using namespace std; + + +class Request: public xmlrpc_c::method +{ +public: + /** + * Wraps the actual execution function by authorizing the user + * and calling the request_execute virtual function + * @param _paramlist list of XML parameters + * @param _retval value to be returned to the client + */ + virtual void execute( + xmlrpc_c::paramList const& _paramList, + xmlrpc_c::value * const _retval); + +protected: + + Request(const string& mn, + const string& signature, + const string& help): method_name(mn), retval(0) + { + _signature = signature; + _help = help; + }; + + virtual ~Request(){}; + + + /** + * Actual Execution method for the request. Must be implemented by the + * XML-RPC requests + * @param uid of the user making the request + * @param gid of the user making the request + * @param _paramlist of the XML-RPC call (complete list) + */ + virtual void request_execute(int uid, + int gid, + xmlrpc_c::paramList const& _paramList) = 0; + + /** + * Builds an XML-RPC response updating retval. After calling this function + * the xml-rpc excute method should return + * @param val to be returned to the client + */ + void success_response(int val); + + /** + * Builds an XML-RPC response updating retval. After calling this function + * the xml-rpc excute method should return + * @param val string to be returned to the client + */ + void success_response(const string& val); + + /** + * Builds an XML-RPC response updating retval. After calling this function + * the xml-rpc excute method should return + * @param ec error code for this call + * @param val string representation of the error + */ + void failure_response(RequestManager::ErrorCode ec, const string& val); + + /** + * Logs authorization errors + * @param action authorization action + * @param object object that needs to be authorized + * @param uid user that is authorized + * @param id id of the object, -1 for Pool + * @returns string for logging + */ + string authorization_error (const string &action, + const string &object, + int uid, + int id); + /** + * Logs authenticate errors + * @returns string for logging + */ + string authenticate_error (); + + /** + * Logs get object errors + * @param object over which the get failed + * @param id of the object over which the get failed + * @returns string for logging + */ + string get_error (const string &object, + int id); + + /** + * Logs action errors + * @param action that triggered the error + * @param object over which the action was applied + * @param id id of the object, -1 for Pool, -2 for no-id objects + * (allocate error, parse error) + * @param rc returned error code (NULL to ignore) + * @returns string for logging + */ + string action_error (const string &action, + const string &object, + int id, + int rc); +private: + /** + * The name of the XML-RPC method + */ + string method_name; + + /** + * Session token from the OpenNebula XML-RPC API + */ + string session; + + /** + * Return value of the request from libxmlrpc-c + */ + xmlrpc_c::value * retval; +}; + +#endif //REQUEST_H_ + diff --git a/include/RequestManager.h b/include/RequestManager.h index 0df3cd2487..fb44e7d732 100644 --- a/include/RequestManager.h +++ b/include/RequestManager.h @@ -88,6 +88,13 @@ public: am.trigger(ACTION_FINALIZE,0); }; + enum ErrorCode { + AUTHENTICATION = 0x0100, + AUTHORIZATION = 0x0200, + GET = 0x0400, + ACTION = 0x0800 + }; + private: //-------------------------------------------------------------------------- diff --git a/src/rm/Request.cc b/src/rm/Request.cc new file mode 100644 index 0000000000..78e9253e4b --- /dev/null +++ b/src/rm/Request.cc @@ -0,0 +1,187 @@ +/* -------------------------------------------------------------------------- */ +/* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */ +/* */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +#include "Request.h" +#include "Nebula.h" + + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void Request::execute( + xmlrpc_c::paramList const& _paramList, + xmlrpc_c::value * const _retval) +{ + int uid; + int gid; + + retval = _retval; + session = xmlrpc_c::value_string (_paramList.getString(0)); + + Nebula& nd = Nebula::instance(); + UserPool* upool = nd.get_upool(); + + NebulaLog::log("ReM",Log::DEBUG, method_name + " method invoked"); + +if (true) // if ( upool->authenticate(uid, gid) == false ) + { + failure_response(RequestManager::AUTHENTICATION, + authenticate_error()); + } + else + { + request_execute(uid, gid, _paramList); + } +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void Request::failure_response(RequestManager::ErrorCode ec, + const string& str_val) +{ + vector arrayData; + + arrayData.push_back(xmlrpc_c::value_boolean(false)); + arrayData.push_back(xmlrpc_c::value_string(str_val)); + arrayData.push_back(xmlrpc_c::value_int(ec)); + + xmlrpc_c::value_array arrayresult(arrayData); + + *retval = arrayresult; + + NebulaLog::log("ReM",Log::ERROR,str_val); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +void Request::success_response(int id) +{ + vector arrayData; + + arrayData.push_back(xmlrpc_c::value_boolean(true)); + arrayData.push_back(xmlrpc_c::value_int(id)); + + xmlrpc_c::value_array arrayresult(arrayData); + + *retval = arrayresult; +} + +/* -------------------------------------------------------------------------- */ + +void Request::success_response(const string& val) +{ + vector arrayData; + + arrayData.push_back(xmlrpc_c::value_boolean(true)); + arrayData.push_back(xmlrpc_c::value_string(val)); + + xmlrpc_c::value_array arrayresult(arrayData); + + *retval = arrayresult; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string Request::authorization_error (const string &action, + const string &object, + int uid, + int id) +{ + ostringstream oss; + + oss << "[" << method_name << "]" << " User [" << uid << "] not authorized" + << " to perform " << action << " on " << object; + + + if ( id != -1 ) + { + oss << " [" << id << "]."; + } + else + { + oss << " Pool"; + } + + return oss.str(); +} + +/* -------------------------------------------------------------------------- */ + +string Request::authenticate_error() +{ + ostringstream oss; + + oss << "[" << method_name << "]" << " User couldn't be authenticated," << + " aborting call."; + + return oss.str(); +} + +/* -------------------------------------------------------------------------- */ + +string Request::get_error (const string &object, + int id) +{ + ostringstream oss; + + oss << "[" << method_name << "]" << " Error getting " << + object; + + if ( id != -1 ) + { + oss << " [" << id << "]."; + } + else + { + oss << " Pool."; + } + + return oss.str(); +} +/* -------------------------------------------------------------------------- */ + +string Request::action_error (const string &action, + const string &object, + int id, + int rc) +{ + ostringstream oss; + + oss << "[" << method_name << "]" << " Error trying to " << action << " " + << object; + + switch(id) + { + case -2: + break; + case -1: + oss << "Pool."; + break; + default: + oss << " [" << id << "]."; + break; + } + + if ( rc != 0 ) + { + oss << " Returned error code [" << rc << "]."; + } + + return oss.str(); +} diff --git a/src/rm/SConstruct b/src/rm/SConstruct index c4b03a6a75..093f876235 100644 --- a/src/rm/SConstruct +++ b/src/rm/SConstruct @@ -22,6 +22,7 @@ lib_name='nebula_rm' #Sources to generate the library source_files=[ + 'Request.cc', 'RequestManager.cc', 'RequestManagerAction.cc', 'RequestManagerAllocate.cc',