From 9d90f12602d02ceef925dec53c0eb029d05e9133 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Thu, 6 Oct 2016 17:09:29 +0200 Subject: [PATCH] B #4850: Invoke federation master when creating users from the driver callbacks --- src/client/Client.cc | 22 ++++++++-- src/um/UserPool.cc | 97 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 112 insertions(+), 7 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index 7194f2e166..6b906137b7 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -131,11 +131,15 @@ void Client::call(const std::string &method, const std::string format, std::string::const_iterator i; - std::string sval; - int ival; - bool bval; + std::string sval; + int ival; + bool bval; + + std::set * vval; + std::set::iterator it; const char* pval; + vector x_vval; xmlrpc_c::paramList plist; @@ -164,6 +168,18 @@ void Client::call(const std::string &method, const std::string format, plist.add(xmlrpc_c::value_boolean(bval)); break; + case 'I': + vval = static_cast *>(va_arg(args, + std::set *)); + + 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; } diff --git a/src/um/UserPool.cc b/src/um/UserPool.cc index efc8b07d71..76d28771b5 100644 --- a/src/um/UserPool.cc +++ b/src/um/UserPool.cc @@ -225,6 +225,86 @@ error_common: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +static int master_allocate(const string& uname, const string& passwd, + const string& driver, const set& gids, string& error_str) +{ + Client * client = Client::client(); + + xmlrpc_c::value result; + vector values; + + std::ostringstream oss("Cannot allocate user at federation master: ", + std::ios::ate); + try + { + client->call("one.user.allocate", "sssI", &result, uname.c_str(), + passwd.c_str(), driver.c_str(), &gids); + } + catch (exception const& e) + { + oss << e.what(); + error_str = oss.str(); + + return -1; + } + + values = xmlrpc_c::value_array(result).vectorValueValue(); + + if ( xmlrpc_c::value_boolean(values[0]) == false ) + { + std::string error_xml = xmlrpc_c::value_string(values[1]); + + oss << error_xml; + error_str = oss.str(); + + return -1; + } + + int oid = xmlrpc_c::value_int(values[1]); + + return oid; +} + +/* -------------------------------------------------------------------------- */ + +static int master_chgrp(int user_id, int group_id, string& error_str) +{ + Client * client = Client::client(); + + xmlrpc_c::value result; + vector values; + + std::ostringstream oss("Cannot change user group at federation master: ", + std::ios::ate); + try + { + client->call("one.user.chgrp", "ii", &result, user_id, group_id); + } + catch (exception const& e) + { + oss << e.what(); + error_str = oss.str(); + + return -1; + } + + values = xmlrpc_c::value_array(result).vectorValueValue(); + + if ( xmlrpc_c::value_boolean(values[0]) == false ) + { + std::string error_xml = xmlrpc_c::value_string(values[1]); + + oss << error_xml; + error_str = oss.str(); + + return -1; + } + + return 0; +}; + +/* -------------------------------------------------------------------------- */ + int UserPool::allocate ( int * oid, const string& uname, @@ -249,11 +329,20 @@ int UserPool::allocate ( if (nd.is_federation_slave()) { - NebulaLog::log("ONE",Log::ERROR, - "UserPool::allocate called, but this " - "OpenNebula is a federation slave"); + *oid = master_allocate(uname, password, auth, gids, error_str); - return -1; + if ( *oid < 0 ) + { + NebulaLog::log("ONE", Log::ERROR, error_str); + return -1; + } + + if ( master_chgrp(*oid, gid, error_str) == -1 ) + { + NebulaLog::log("ONE", Log::ERROR, error_str); + } + + return *oid; } // Check username and password