mirror of
https://github.com/OpenNebula/one.git
synced 2026-11-10 06:24:35 +09:00
* Do not reset vote on followers upon successful election
* Cache one_auth secret to fix mt issue and improve heartbeat
performance
* Remove debug message when a record is not loaded
* Remove default timeout for curl library
(cherry picked from commit a6addb314e)
267 lines
7.0 KiB
C++
267 lines
7.0 KiB
C++
/* -------------------------------------------------------------------------- */
|
|
/* Copyright 2002-2017, 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. */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#include "Client.h"
|
|
|
|
#include <fstream>
|
|
#include <pwd.h>
|
|
#include <stdlib.h>
|
|
#include <stdexcept>
|
|
|
|
#include <limits.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <sstream>
|
|
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
|
|
Client * Client::_client = 0;
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
Client::Client(const string& secret, const string& endpoint,
|
|
size_t message_size, unsigned int tout)
|
|
{
|
|
string error;
|
|
char * xmlrpc_env;
|
|
|
|
if (!secret.empty())
|
|
{
|
|
one_auth = secret;
|
|
}
|
|
else if (read_oneauth(one_auth, error) != 0 )
|
|
{
|
|
NebulaLog::log("XMLRPC", Log::ERROR, error);
|
|
throw runtime_error(error);
|
|
}
|
|
|
|
if(!endpoint.empty())
|
|
{
|
|
one_endpoint = endpoint;
|
|
}
|
|
else if ( (xmlrpc_env = getenv("ONE_XMLRPC"))!= 0 )
|
|
{
|
|
one_endpoint = xmlrpc_env;
|
|
}
|
|
else
|
|
{
|
|
one_endpoint = "http://localhost:2633/RPC2";
|
|
}
|
|
|
|
xmlrpc_limit_set(XMLRPC_XML_SIZE_LIMIT_ID, message_size);
|
|
|
|
timeout = tout * 1000;
|
|
};
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
int Client::read_oneauth(string &secret, string& error_msg)
|
|
{
|
|
string one_auth_file;
|
|
ifstream file;
|
|
|
|
const char * one_auth_env = getenv("ONE_AUTH");
|
|
|
|
if (!one_auth_env) //No $ONE_AUTH, read $HOME/.one/one_auth
|
|
{
|
|
struct passwd * pw_ent;
|
|
|
|
pw_ent = getpwuid(getuid());
|
|
|
|
if ((pw_ent == NULL) || (pw_ent->pw_dir == NULL))
|
|
{
|
|
error_msg = "Could not get one_auth file location";
|
|
return -1;
|
|
}
|
|
|
|
one_auth_file = pw_ent->pw_dir;
|
|
one_auth_file += "/.one/one_auth";
|
|
|
|
one_auth_env = one_auth_file.c_str();
|
|
}
|
|
|
|
file.open(one_auth_env);
|
|
|
|
if (!file.good())
|
|
{
|
|
error_msg = "Could not open file " + one_auth_file;
|
|
return -1;
|
|
}
|
|
|
|
getline(file, secret);
|
|
|
|
if (file.fail())
|
|
{
|
|
error_msg = "Error reading file " + one_auth_file;
|
|
|
|
file.close();
|
|
return -1;
|
|
}
|
|
|
|
file.close();
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
void Client::call(const std::string &method, const std::string format,
|
|
xmlrpc_c::value * const result, ...)
|
|
{
|
|
va_list args;
|
|
va_start(args, result);
|
|
|
|
std::string::const_iterator i;
|
|
|
|
std::string sval;
|
|
int ival;
|
|
bool bval;
|
|
|
|
std::set<int> * vval;
|
|
std::set<int>::iterator it;
|
|
|
|
const char* pval;
|
|
vector<xmlrpc_c::value> x_vval;
|
|
|
|
xmlrpc_c::paramList plist;
|
|
|
|
plist.add(xmlrpc_c::value_string(one_auth));
|
|
|
|
for (i = format.begin(); i != format.end(); ++i)
|
|
{
|
|
switch(*i)
|
|
{
|
|
case 's':
|
|
pval = static_cast<const char*>(va_arg(args, char *));
|
|
sval = pval;
|
|
|
|
plist.add(xmlrpc_c::value_string(sval));
|
|
break;
|
|
|
|
case 'i':
|
|
ival = va_arg(args, int);
|
|
|
|
plist.add(xmlrpc_c::value_int(ival));
|
|
break;
|
|
|
|
case 'b':
|
|
bval = va_arg(args, int);
|
|
|
|
plist.add(xmlrpc_c::value_boolean(bval));
|
|
break;
|
|
|
|
case 'I':
|
|
vval = static_cast<std::set<int> *>(va_arg(args,
|
|
std::set<int> *));
|
|
|
|
for (it = vval->begin(); it != vval->end(); ++it)
|
|
{
|
|
x_vval.push_back(xmlrpc_c::value_int(*it));
|
|
}
|
|
|
|
plist.add(xmlrpc_c::value_array(x_vval));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
va_end(args);
|
|
|
|
call(method, plist, result);
|
|
};
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
void Client::call(const std::string& method, const xmlrpc_c::paramList& plist,
|
|
xmlrpc_c::value * const result)
|
|
{
|
|
xmlrpc_c::clientXmlTransport_curl ctrans(
|
|
xmlrpc_c::clientXmlTransport_curl::constrOpt().timeout(timeout));
|
|
|
|
xmlrpc_c::carriageParm_curl0 cparam(one_endpoint);
|
|
|
|
xmlrpc_c::client_xml client(&ctrans);
|
|
xmlrpc_c::rpcPtr rpc(method, plist);
|
|
|
|
rpc->start(&client, &cparam);
|
|
|
|
client.finishAsync(xmlrpc_c::timeout());
|
|
|
|
if (rpc->isSuccessful())
|
|
{
|
|
*result = rpc->getResult();
|
|
}
|
|
else
|
|
{
|
|
xmlrpc_c::fault failure = rpc->getFault();
|
|
|
|
girerr::error(failure.getDescription());
|
|
}
|
|
};
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
int Client::call(const std::string& endpoint, const std::string& method,
|
|
const xmlrpc_c::paramList& plist, unsigned int _timeout,
|
|
xmlrpc_c::value * const result, std::string& error)
|
|
{
|
|
xmlrpc_c::clientXmlTransport_curl transport(
|
|
xmlrpc_c::clientXmlTransport_curl::constrOpt().timeout(_timeout));
|
|
|
|
xmlrpc_c::carriageParm_curl0 carriage(endpoint);
|
|
|
|
xmlrpc_c::client_xml client(&transport);
|
|
xmlrpc_c::rpcPtr rpc_client(method, plist);
|
|
|
|
int xml_rc = 0;
|
|
|
|
try
|
|
{
|
|
rpc_client->start(&client, &carriage);
|
|
|
|
client.finishAsync(xmlrpc_c::timeout());
|
|
|
|
if ( rpc_client->isSuccessful() )
|
|
{
|
|
*result = rpc_client->getResult();
|
|
}
|
|
else //RPC failed
|
|
{
|
|
xmlrpc_c::fault failure = rpc_client->getFault();
|
|
|
|
error = failure.getDescription();
|
|
xml_rc = -1;
|
|
}
|
|
}
|
|
catch (exception const& e)
|
|
{
|
|
error = e.what();
|
|
xml_rc = -1;
|
|
}
|
|
|
|
return xml_rc;
|
|
}
|
|
|