1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-25 06:03:36 +03:00

Merge branch 'feature-2632'

This commit is contained in:
Carlos Martín 2014-01-16 17:19:53 +01:00
commit 31d4b65d38
21 changed files with 961 additions and 118 deletions

View File

@ -20,7 +20,7 @@
#include "PoolSQL.h"
#include "ObjectCollection.h"
#include "User.h"
#include "Quotas.h"
#include "GroupQuotas.h"
using namespace std;
@ -97,7 +97,7 @@ public:
/**
* Object quotas, provides set and check interface
*/
Quotas quota;
GroupQuotas quota;
private:
@ -114,10 +114,7 @@ private:
Group(int id, const string& name):
PoolObjectSQL(id,GROUP,name,-1,-1,"","",table),
ObjectCollection("USERS"),
quota("/GROUP/DATASTORE_QUOTA",
"/GROUP/NETWORK_QUOTA",
"/GROUP/IMAGE_QUOTA",
"/GROUP/VM_QUOTA")
quota()
{
// Allow users in this group to see it
group_u = 1;
@ -156,31 +153,61 @@ private:
*/
static int bootstrap(SqlDB * db)
{
ostringstream oss(Group::db_bootstrap);
int rc;
return db->exec(oss);
ostringstream oss_group(Group::db_bootstrap);
ostringstream oss_quota(GroupQuotas::db_bootstrap);
rc = db->exec(oss_group);
rc += db->exec(oss_quota);
return rc;
};
/**
* Reads the Group (identified with its OID) from the database.
* @param db pointer to the db
* @return 0 on success
*/
int select(SqlDB * db);
/**
* Reads the Group (identified with its OID) from the database.
* @param db pointer to the db
* @param name of the group
* @param uid of the owner
*
* @return 0 on success
*/
int select(SqlDB * db, const string& name, int uid);
/**
* Reads the Group quotas from the database.
* @param db pointer to the db
* @return 0 on success
*/
int select_quotas(SqlDB * db);
/**
* Drops the group from the database
* @param db pointer to the db
* @return 0 on success
*/
int drop(SqlDB *db);
/**
* Writes the Group in the database.
* @param db pointer to the db
* @return 0 on success
*/
int insert(SqlDB *db, string& error_str)
{
return insert_replace(db, false, error_str);
}
int insert(SqlDB *db, string& error_str);
/**
* Writes/updates the Group's data fields in the database.
* @param db pointer to the db
* @return 0 on success
*/
int update(SqlDB *db)
{
string error_str;
return insert_replace(db, true, error_str);
}
int update(SqlDB *db);
/**
* Function to print the Group object into a string in

View File

@ -150,20 +150,7 @@ public:
*
* @return 0 on success
*/
int dump(ostringstream& oss, const string& where)
{
return PoolSQL::dump(oss, "GROUP_POOL", Group::table, where);
};
protected:
/**
* Adds the default quotas xml element, right after all the
* pool objects
*
* @param oss The output stream to dump the xml contents
*/
virtual void add_extra_xml(ostringstream& oss);
int dump(ostringstream& oss, const string& where);
private:
@ -175,6 +162,15 @@ private:
{
return new Group(-1,"");
};
/**
* Callback function to get output in XML format
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
int dump_cb(void * _oss, int num, char **values, char **names);
};
#endif /*GROUP_POOL_H_*/

58
include/GroupQuotas.h Normal file
View File

@ -0,0 +1,58 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs */
/* */
/* 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 GROUP_QUOTAS_H_
#define GROUP_QUOTAS_H_
#include "Quotas.h"
class GroupQuotas : public Quotas
{
public:
GroupQuotas():Quotas(
"/QUOTAS/DATASTORE_QUOTA",
"/QUOTAS/NETWORK_QUOTA",
"/QUOTAS/IMAGE_QUOTA",
"/QUOTAS/VM_QUOTA"){};
// *************************************************************************
// DataBase implementation
// *************************************************************************
static const char * db_names;
static const char * db_bootstrap;
static const char * db_table;
static const char * db_oid_column;
protected:
const char * table() const
{
return db_table;
};
const char * table_names() const
{
return db_names;
};
const char * table_oid_column() const
{
return db_oid_column;
};
};
#endif /*GROUP_QUOTAS_H_*/

View File

@ -21,10 +21,11 @@
#include "QuotaNetwork.h"
#include "QuotaVirtualMachine.h"
#include "QuotaImage.h"
#include "ObjectSQL.h"
class ObjectXML;
class Quotas
class Quotas : public ObjectSQL
{
public:
Quotas(const char * _ds_xpath,
@ -176,6 +177,14 @@ public:
*/
string& to_xml(string& xml) const;
/**
* Generates a string representation of the quotas in XML format, enclosed
* in the QUOTAS tag
* @param xml the string to store the XML
* @return the same xml string to use it in << compounds
*/
string& to_xml_db(string& xml) const;
/**
* Builds quota object from an ObjectXML
* @param object_xml pointer to the ObjectXML
@ -183,6 +192,9 @@ public:
*/
int from_xml(ObjectXML * object_xml);
// TODO: remove previous method, leave this one only
int from_xml(const string& xml);
/**
* Delete VM related usage (network, image and compute) from quota counters.
* for the given user and group
@ -217,6 +229,51 @@ public:
*/
static void quota_del(QuotaType type, int uid, int gid, Template * tmpl);
//--------------------------------------------------------------------------
// Database
//--------------------------------------------------------------------------
/**
* Reads the ObjectSQL (identified with its OID) from the database.
* @param db pointer to the db
* @return 0 on success
*/
int select(SqlDB * db);
/**
* Writes the Quotas in the database.
* @param db pointer to the db
* @return 0 on success
*/
int insert(SqlDB *db, string& error_str)
{
return insert_replace(db, false, error_str);
};
/**
* Writes/updates the Quotas fields in the database.
* @param db pointer to the db
* @return 0 on success
*/
int update(SqlDB *db)
{
string error_str;
return insert_replace(db, true, error_str);
}
/**
* Removes the Quotas from the database.
* @param db pointer to the db
* @return 0 on success
*/
int drop(SqlDB * db);
/**
* User/Group oid. Must be set before a DB write operation
*/
int oid;
protected:
/**
* This is an specialized constructor only for derived Quotas classes.
@ -227,6 +284,7 @@ protected:
const char * _img_xpath,
const char * _vm_xpath,
bool is_deafult):
oid(-1),
datastore_quota(is_deafult),
network_quota(is_deafult),
image_quota(is_deafult),
@ -237,6 +295,21 @@ protected:
vm_xpath(_vm_xpath)
{};
virtual const char * table() const
{
return 0;
};
virtual const char * table_names() const
{
return 0;
};
virtual const char * table_oid_column() const
{
return 0;
};
private:
//--------------------------------------------------------------------------
// Usage Counters and Quotas
@ -286,6 +359,27 @@ private:
*/
const char * vm_xpath;
//--------------------------------------------------------------------------
// Database
//--------------------------------------------------------------------------
/**
* Callback function to read a Quotas object (Quotas::select)
* @param num the number of columns read from the DB
* @para names the column names
* @para vaues the column values
* @return 0 on success
*/
int select_cb(void *nil, int num, char **values, char **names);
/**
* Execute an INSERT or REPLACE Sql query.
* @param db The SQL DB
* @param replace Execute an INSERT or a REPLACE
* @param error_str Returns the error reason, if any
* @return 0 one success
*/
int insert_replace(SqlDB *db, bool replace, string& error_str);
};
#endif /*QUOTABLE_H_*/

View File

@ -19,7 +19,7 @@
#include "PoolSQL.h"
#include "UserTemplate.h"
#include "Quotas.h"
#include "UserQuotas.h"
#include "ObjectCollection.h"
using namespace std;
@ -171,7 +171,7 @@ public:
/**
* Object quotas, provides set and check interface
*/
Quotas quota;
UserQuotas quota;
/**
* Returns the UMASK template attribute (read as an octal number), or the
@ -316,11 +316,41 @@ private:
*/
static int bootstrap(SqlDB * db)
{
ostringstream oss_user(User::db_bootstrap);
int rc;
return db->exec(oss_user);
ostringstream oss_user(User::db_bootstrap);
ostringstream oss_quota(UserQuotas::db_bootstrap);
rc = db->exec(oss_user);
rc += db->exec(oss_quota);
return rc;
};
/**
* Reads the User (identified with its OID) from the database.
* @param db pointer to the db
* @return 0 on success
*/
int select(SqlDB * db);
/**
* Reads the User (identified with its OID) from the database.
* @param db pointer to the db
* @param name of the user
* @param uid of the owner
*
* @return 0 on success
*/
int select(SqlDB * db, const string& name, int uid);
/**
* Drops the user from the database
* @param db pointer to the db
* @return 0 on success
*/
int drop(SqlDB *db);
/**
* Rebuilds the object from an xml formatted string
* @param xml_str The xml-formatted string
@ -353,10 +383,7 @@ protected:
bool _enabled):
PoolObjectSQL(id,USER,_uname,-1,_gid,"",_gname,table),
ObjectCollection("GROUPS"),
quota("/USER/DATASTORE_QUOTA",
"/USER/NETWORK_QUOTA",
"/USER/IMAGE_QUOTA",
"/USER/VM_QUOTA"),
quota(),
password(_password),
auth_driver(_auth_driver),
enabled(_enabled),
@ -381,26 +408,26 @@ protected:
static const char * table;
/**
* Reads the User quotas from the database.
* @param db pointer to the db
* @return 0 on success
*/
int select_quotas(SqlDB * db);
/**
* Writes the User in the database.
* @param db pointer to the db
* @return 0 on success
*/
int insert(SqlDB *db, string& error_str)
{
return insert_replace(db, false, error_str);
};
int insert(SqlDB *db, string& error_str);
/**
* Writes/updates the User data fields in the database.
* @param db pointer to the db
* @return 0 on success
*/
int update(SqlDB *db)
{
string error_str;
return insert_replace(db, true, error_str);
}
int update(SqlDB *db);
};
#endif /*USER_H_*/

View File

@ -150,10 +150,7 @@ public:
*
* @return 0 on success
*/
int dump(ostringstream& oss, const string& where)
{
return PoolSQL::dump(oss, "USER_POOL", User::table, where);
};
int dump(ostringstream& oss, const string& where);
/**
* Name for the OpenNebula core authentication process
@ -191,16 +188,6 @@ public:
*/
static const int ONEADMIN_ID;
protected:
/**
* Adds the default quotas xml element, right after all the
* pool objects
*
* @param oss The output stream to dump the xml contents
*/
virtual void add_extra_xml(ostringstream& oss);
private:
//--------------------------------------------------------------------------
// Configuration Attributes for Users
@ -253,6 +240,17 @@ private:
return new User(-1,-1,"","","",UserPool::CORE_AUTH,true);
};
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
/**
* Callback function to get output in XML format
* @param num the number of columns read from the DB
* @param names the column names
* @param vaues the column values
* @return 0 on success
*/
int dump_cb(void * _oss, int num, char **values, char **names);
};
#endif /*USER_POOL_H_*/

58
include/UserQuotas.h Normal file
View File

@ -0,0 +1,58 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs */
/* */
/* 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 USER_QUOTAS_H_
#define USER_QUOTAS_H_
#include "Quotas.h"
class UserQuotas : public Quotas
{
public:
UserQuotas():Quotas(
"/QUOTAS/DATASTORE_QUOTA",
"/QUOTAS/NETWORK_QUOTA",
"/QUOTAS/IMAGE_QUOTA",
"/QUOTAS/VM_QUOTA"){};
// *************************************************************************
// DataBase implementation
// *************************************************************************
static const char * db_names;
static const char * db_bootstrap;
static const char * db_table;
static const char * db_oid_column;
protected:
const char * table() const
{
return db_table;
};
const char * table_names() const
{
return db_names;
};
const char * table_oid_column() const
{
return db_oid_column;
};
};
#endif /*USER_QUOTAS_H_*/

View File

@ -65,6 +65,15 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
prefix = '/GROUP_POOL/DEFAULT_GROUP_QUOTAS/'
group_pool = @group_pool
quotas = group_pool.to_hash()['GROUP_POOL']['QUOTAS']
quotas_hash = Hash.new
if (!quotas.nil?)
quotas.each do |q|
quotas_hash[q['ID']] = q
end
end
table = CLIHelper::ShowTable.new(config_file, self) do
column :ID, "ONE identifier for the Group", :size=>4 do |d|
d["ID"]
@ -88,48 +97,53 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
end
column :VMS , "Number of VMS", :size=>9 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
limit = d['VM_QUOTA']['VM']["VMS"]
begin
q = quotas_hash[d['ID']]
limit = q['VM_QUOTA']['VM']["VMS"]
if limit == "-1"
limit = group_pool["#{prefix}VM_QUOTA/VM/VMS"]
limit = "0" if limit.nil? || limit == ""
end
"%3d / %3d" % [d['VM_QUOTA']['VM']["VMS_USED"], limit]
else
"%3d / %3d" % [q['VM_QUOTA']['VM']["VMS_USED"], limit]
rescue NoMethodError
"-"
end
end
column :MEMORY, "Total memory allocated to user VMs", :size=>17 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
limit = d['VM_QUOTA']['VM']["MEMORY"]
begin
q = quotas_hash[d['ID']]
limit = q['VM_QUOTA']['VM']["MEMORY"]
if limit == "-1"
limit = group_pool["#{prefix}VM_QUOTA/VM/MEMORY"]
limit = "0" if limit.nil? || limit == ""
end
d['VM_QUOTA']['VM']['MEMORY_USED']
"%7s / %7s" % [OpenNebulaHelper.unit_to_str(d['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M"),
"%7s / %7s" % [OpenNebulaHelper.unit_to_str(q['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")]
else
rescue NoMethodError
"-"
end
end
column :CPU, "Total CPU allocated to user VMs", :size=>11 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
limit = d['VM_QUOTA']['VM']["CPU"]
begin
q = quotas_hash[d['ID']]
limit = q['VM_QUOTA']['VM']["CPU"]
if limit == "-1"
limit = group_pool["#{prefix}VM_QUOTA/VM/CPU"]
limit = "0" if limit.nil? || limit == ""
end
"%3.1f / %3.1f" % [d['VM_QUOTA']['VM']["CPU_USED"], limit]
else
"%3.1f / %3.1f" % [q['VM_QUOTA']['VM']["CPU_USED"], limit]
rescue NoMethodError
"-"
end
end

View File

@ -151,6 +151,15 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
prefix = '/USER_POOL/DEFAULT_USER_QUOTAS/'
user_pool = @user_pool
quotas = user_pool.to_hash()['USER_POOL']['QUOTAS']
quotas_hash = Hash.new
if (!quotas.nil?)
quotas.each do |q|
quotas_hash[q['ID']] = q
end
end
table = CLIHelper::ShowTable.new(config_file, self) do
column :ID, "ONE identifier for the User", :size=>4 do |d|
d["ID"]
@ -168,49 +177,54 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
d["AUTH_DRIVER"]
end
column :VMS , "Number of VMS", :size=>9 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
limit = d['VM_QUOTA']['VM']["VMS"]
column :VMS , "Number of VMS", :size=>9 do |d|
begin
q = quotas_hash[d['ID']]
limit = q['VM_QUOTA']['VM']["VMS"]
if limit == "-1"
limit = user_pool["#{prefix}VM_QUOTA/VM/VMS"]
limit = "0" if limit.nil? || limit == ""
end
"%3d / %3d" % [d['VM_QUOTA']['VM']["VMS_USED"], limit]
else
"%3d / %3d" % [q['VM_QUOTA']['VM']["VMS_USED"], limit]
rescue NoMethodError
"-"
end
end
end
column :MEMORY, "Total memory allocated to user VMs", :size=>17 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
limit = d['VM_QUOTA']['VM']["MEMORY"]
begin
q = quotas_hash[d['ID']]
limit = q['VM_QUOTA']['VM']["MEMORY"]
if limit == "-1"
limit = user_pool["#{prefix}VM_QUOTA/VM/MEMORY"]
limit = "0" if limit.nil? || limit == ""
end
d['VM_QUOTA']['VM']['MEMORY_USED']
"%7s / %7s" % [OpenNebulaHelper.unit_to_str(d['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M"),
"%7s / %7s" % [OpenNebulaHelper.unit_to_str(q['VM_QUOTA']['VM']["MEMORY_USED"].to_i,{},"M"),
OpenNebulaHelper.unit_to_str(limit.to_i,{},"M")]
else
rescue NoMethodError
"-"
end
end
column :CPU, "Total CPU allocated to user VMs", :size=>11 do |d|
if d.has_key?('VM_QUOTA') and d['VM_QUOTA'].has_key?('VM')
limit = d['VM_QUOTA']['VM']["CPU"]
begin
q = quotas_hash[d['ID']]
limit = q['VM_QUOTA']['VM']["CPU"]
if limit == "-1"
limit = user_pool["#{prefix}VM_QUOTA/VM/CPU"]
limit = "0" if limit.nil? || limit == ""
end
"%3.1f / %3.1f" % [d['VM_QUOTA']['VM']["CPU_USED"], limit]
else
"%3.1f / %3.1f" % [q['VM_QUOTA']['VM']["CPU_USED"], limit]
rescue NoMethodError
"-"
end
end

View File

@ -37,6 +37,103 @@ const char * Group::db_bootstrap = "CREATE TABLE IF NOT EXISTS group_pool ("
/* Group :: Database Access Functions */
/* ************************************************************************ */
int Group::select(SqlDB * db)
{
int rc;
rc = PoolObjectSQL::select(db);
if ( rc != 0 )
{
return rc;
}
return select_quotas(db);
}
/* -------------------------------------------------------------------------- */
int Group::select(SqlDB * db, const string& name, int uid)
{
int rc;
rc = PoolObjectSQL::select(db,name,uid);
if ( rc != 0 )
{
return rc;
}
return select_quotas(db);
}
/* -------------------------------------------------------------------------- */
int Group::select_quotas(SqlDB * db)
{
quota.oid = oid;
return quota.select(db);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Group::drop(SqlDB * db)
{
int rc;
rc = PoolObjectSQL::drop(db);
if ( rc == 0 )
{
rc += quota.drop(db);
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Group::insert(SqlDB *db, string& error_str)
{
int rc;
rc = insert_replace(db, false, error_str);
quota.oid = oid;
if (rc == 0)
{
rc = quota.insert(db, error_str);
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Group::update(SqlDB *db)
{
int rc;
string error_str;
rc = insert_replace(db, true, error_str);
quota.oid = oid;
if (rc == 0)
{
rc = quota.update(db);
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Group::insert_replace(SqlDB *db, bool replace, string& error_str)
{
ostringstream oss;
@ -147,20 +244,16 @@ string& Group::to_xml_extended(string& xml, bool extended) const
{
ostringstream oss;
string collection_xml;
string quota_xml;
set<pair<int,int> >::const_iterator it;
ObjectCollection::to_xml(collection_xml);
quota.to_xml(quota_xml);
oss <<
"<GROUP>" <<
"<ID>" << oid << "</ID>" <<
"<NAME>" << name << "</NAME>" <<
collection_xml <<
quota_xml;
collection_xml;
for (it = providers.begin(); it != providers.end(); it++)
{
@ -173,8 +266,11 @@ string& Group::to_xml_extended(string& xml, bool extended) const
if (extended)
{
string quota_xml;
string def_quota_xml;
oss << Nebula::instance().get_default_group_quota().to_xml(def_quota_xml);
oss << quota.to_xml(quota_xml)
<< Nebula::instance().get_default_group_quota().to_xml(def_quota_xml);
}
oss << "</GROUP>";
@ -219,9 +315,6 @@ int Group::from_xml(const string& xml)
ObjectXML::free_nodes(content);
content.clear();
// Quotas
rc += quota.from_xml(this);
// Set of resource providers
ObjectXML::get_nodes("/GROUP/RESOURCE_PROVIDER", content);

View File

@ -169,10 +169,57 @@ int GroupPool::drop(PoolObjectSQL * objsql, string& error_msg)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void GroupPool::add_extra_xml(ostringstream& oss)
int GroupPool::dump(ostringstream& oss, const string& where)
{
string def_quota_xml;
int rc;
string def_quota_xml;
ostringstream cmd;
cmd << "SELECT " << Group::table << ".body, "
<< GroupQuotas::db_table << ".body"
<< " FROM " << Group::table << " LEFT JOIN " << GroupQuotas::db_table
<< " ON " << Group::table << ".oid=" << GroupQuotas::db_table << ".group_oid";
if ( !where.empty() )
{
cmd << " WHERE " << where;
}
cmd << " ORDER BY oid";
oss << "<GROUP_POOL>";
set_callback(static_cast<Callbackable::Callback>(&GroupPool::dump_cb),
static_cast<void *>(&oss));
rc = db->exec(cmd, this);
unset_callback();
oss << Nebula::instance().get_default_group_quota().to_xml(def_quota_xml);
oss << "</GROUP_POOL>";
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int GroupPool::dump_cb(void * _oss, int num, char **values, char **names)
{
ostringstream * oss;
oss = static_cast<ostringstream *>(_oss);
if ( (!values[0]) || (num != 2) )
{
return -1;
}
*oss << values[0] << values[1];
return 0;
}
/* -------------------------------------------------------------------------- */

31
src/group/GroupQuotas.cc Normal file
View File

@ -0,0 +1,31 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs */
/* */
/* 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 "GroupQuotas.h"
/* ************************************************************************** */
/* GroupQuotas :: Database Access Functions */
/* ************************************************************************** */
const char * GroupQuotas::db_table = "group_quotas";
const char * GroupQuotas::db_names = "group_oid, body";
const char * GroupQuotas::db_oid_column = "group_oid";
const char * GroupQuotas::db_bootstrap =
"CREATE TABLE IF NOT EXISTS group_quotas ("
"group_oid INTEGER PRIMARY KEY, body MEDIUMTEXT)";

View File

@ -23,7 +23,8 @@ lib_name='nebula_group'
# Sources to generate the library
source_files=[
'GroupPool.cc',
'Group.cc'
'Group.cc',
'GroupQuotas.cc'
]
# Build library

View File

@ -227,7 +227,9 @@ var OpenNebula = {
if (response[pool_name]) {
pool = response[pool_name][type];
} else { pull = null };
} else {
pool = null;
}
if (pool == null)
{
@ -246,6 +248,49 @@ var OpenNebula = {
{
p_pool[0] = {};
p_pool[0][type] = pool;
return(p_pool);
}
},
"pool_hash_processing": function(pool_name, resource_name, response)
{
var pool;
if (typeof(pool_name) == "undefined")
{
return Error('Incorrect Pool');
}
var p_pool = {};
if (response[pool_name]) {
pool = response[pool_name][resource_name];
} else {
pool = null;
}
if (pool == null)
{
return p_pool;
}
else if (pool.length)
{
for (i=0;i<pool.length;i++)
{
var res = {};
res[resource_name] = pool[i];
p_pool[res[resource_name]['ID']] = res;
}
return(p_pool);
}
else
{
var res = {};
res[resource_name] = pool;
p_pool[res[resource_name]['ID']] = res;
return(p_pool);
}
}
@ -849,8 +894,11 @@ var OpenNebula = {
default_group_quotas = Quotas.default_quotas(response.GROUP_POOL.DEFAULT_GROUP_QUOTAS);
var list = OpenNebula.Helper.pool(resource,response)
var quotas_hash = OpenNebula.Helper.pool_hash_processing(
'GROUP_POOL','QUOTAS',response);
return callback ?
callback(request, list) : null;
callback(request, list, quotas_hash) : null;
},
error: function(response)
{
@ -907,8 +955,11 @@ var OpenNebula = {
default_user_quotas = Quotas.default_quotas(response.USER_POOL.DEFAULT_USER_QUOTAS);
var list = OpenNebula.Helper.pool(resource,response)
var quotas_hash = OpenNebula.Helper.pool_hash_processing(
'USER_POOL','QUOTAS',response);
return callback ?
callback(request, list) : null;
callback(request, list, quotas_hash) : null;
},
error: function(response)
{

View File

@ -683,11 +683,16 @@ function addGroupElement(request,group_json){
}
//updates the list
function updateGroupsView(request, group_list){
function updateGroupsView(request, group_list, quotas_hash){
group_list_json = group_list;
var group_list_array = [];
$.each(group_list,function(){
// Inject the VM group quota. This info is returned separately in the
// pool info call, but the groupElementArray expects it inside the GROUP,
// as it is returned by the individual info call
this.GROUP.VM_QUOTA = quotas_hash[this.GROUP.ID].QUOTAS.VM_QUOTA;
group_list_array.push(groupElementArray(this));
});
updateView(group_list_array,dataTable_groups);

View File

@ -732,12 +732,18 @@ function addUserElement(request,user_json){
}
// Callback to update the list of users
function updateUsersView(request,users_list){
function updateUsersView(request,users_list,quotas_list){
var user_list_array = [];
$.each(users_list,function(){
//if (this.USER.ID == uid)
// dashboardQuotasHTML(this.USER);
// Inject the VM user quota. This info is returned separately in the
// pool info call, but the userElementArray expects it inside the USER,
// as it is returned by the individual info call
this.USER.VM_QUOTA = quotas_list[this.USER.ID].QUOTAS.VM_QUOTA
user_list_array.push(userElementArray(this));
});
updateView(user_list_array,dataTable_users);

View File

@ -91,6 +91,33 @@ string& Quotas::to_xml(string& xml) const
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
string& Quotas::to_xml_db(string& xml) const
{
ostringstream oss;
oss << "<QUOTAS>"
<< "<ID>" << oid << "</ID>"
<< to_xml(xml)
<< "</QUOTAS>";
xml = oss.str();
return xml;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Quotas::from_xml(const string& xml)
{
ObjectXML obj_xml(xml);
return from_xml(&obj_xml);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Quotas::from_xml(ObjectXML * object_xml)
{
vector<xmlNodePtr> content;
@ -135,6 +162,8 @@ int Quotas::from_xml(ObjectXML * object_xml)
object_xml->free_nodes(content);
object_xml->xpath(oid, "/QUOTAS/ID", -1);
return rc;
}
@ -281,3 +310,123 @@ void Quotas::quota_del(QuotaType type, int uid, int gid, Template * tmpl)
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Quotas::select(SqlDB * db)
{
ostringstream oss;
int rc;
set_callback(static_cast<Callbackable::Callback>(&Quotas::select_cb));
oss << "SELECT body FROM " << table()
<< " WHERE " << table_oid_column() << " = " << oid;
rc = db->exec(oss,this);
unset_callback();
if (rc != 0)
{
goto error_id;
}
return 0;
error_id:
oss.str("");
oss << "Error getting quotas for user/group " << oid;
NebulaLog::log("ONE", Log::ERROR, oss);
return -1;
}
/* -------------------------------------------------------------------------- */
int Quotas::select_cb(void *nil, int num, char **values, char **names)
{
if ( (!values[0]) || (num != 1) )
{
return -1;
}
return from_xml(values[0]);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Quotas::insert_replace(SqlDB *db, bool replace, string& error_str)
{
ostringstream oss;
int rc;
string xml_quota;
char * sql_quota_xml;
// Quota fields
sql_quota_xml = db->escape_str(to_xml_db(xml_quota).c_str());
if ( sql_quota_xml == 0 )
{
goto error_quota_body;
}
if ( ObjectXML::validate_xml(sql_quota_xml) != 0 )
{
goto error_quota_xml;
}
// Construct the SQL statement to Insert or Replace
if(replace)
{
oss << "REPLACE";
}
else
{
oss << "INSERT";
}
oss << " INTO " << table() << " ("<< table_names() <<") VALUES ("
<< oid << ","
<< "'" << sql_quota_xml << "')";
rc = db->exec(oss);
db->free_str(sql_quota_xml);
return rc;
error_quota_xml:
db->free_str(sql_quota_xml);
goto error_common;
error_quota_body:
error_str = "Error transforming the Quotas to XML.";
goto error_common;
error_common:
error_str = "Error transforming the Quotas to XML.";
return -1;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int Quotas::drop(SqlDB *db)
{
ostringstream oss;
int rc;
oss << "DELETE FROM " << table()
<< " WHERE " << table_oid_column() << " = " << oid;
rc = db->exec(oss);
return rc;
}

View File

@ -30,7 +30,8 @@ source_files=[
'QuotaVirtualMachine.cc',
'QuotaImage.cc',
'Quotas.cc',
'DefaultQuotas.cc'
'DefaultQuotas.cc',
'UserQuotas.cc'
]
# Build library

View File

@ -47,6 +47,103 @@ const char * User::db_bootstrap = "CREATE TABLE IF NOT EXISTS user_pool ("
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::select(SqlDB * db)
{
int rc;
rc = PoolObjectSQL::select(db);
if ( rc != 0 )
{
return rc;
}
return select_quotas(db);
}
/* -------------------------------------------------------------------------- */
int User::select(SqlDB * db, const string& name, int uid)
{
int rc;
rc = PoolObjectSQL::select(db,name,uid);
if ( rc != 0 )
{
return rc;
}
return select_quotas(db);
}
/* -------------------------------------------------------------------------- */
int User::select_quotas(SqlDB * db)
{
quota.oid = oid;
return quota.select(db);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::drop(SqlDB * db)
{
int rc;
rc = PoolObjectSQL::drop(db);
if ( rc == 0 )
{
rc += quota.drop(db);
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::insert(SqlDB *db, string& error_str)
{
int rc;
rc = insert_replace(db, false, error_str);
quota.oid = oid;
if (rc == 0)
{
rc = quota.insert(db, error_str);
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::update(SqlDB *db)
{
int rc;
string error_str;
rc = insert_replace(db, true, error_str);
quota.oid = oid;
if (rc == 0)
{
rc = quota.update(db);
}
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int User::insert_replace(SqlDB *db, bool replace, string& error_str)
{
ostringstream oss;
@ -155,7 +252,6 @@ string& User::to_xml_extended(string& xml, bool extended) const
ostringstream oss;
string template_xml;
string quota_xml;
string collection_xml;
ObjectCollection::to_xml(collection_xml);
@ -172,13 +268,15 @@ string& User::to_xml_extended(string& xml, bool extended) const
"<PASSWORD>" << password <<"</PASSWORD>" <<
"<AUTH_DRIVER>" << auth_driver <<"</AUTH_DRIVER>"<<
"<ENABLED>" << enabled_int <<"</ENABLED>" <<
obj_template->to_xml(template_xml) <<
quota.to_xml(quota_xml);
obj_template->to_xml(template_xml);
if (extended)
{
string quota_xml;
string def_quota_xml;
oss << Nebula::instance().get_default_user_quota().to_xml(def_quota_xml);
oss << quota.to_xml(quota_xml)
<< Nebula::instance().get_default_user_quota().to_xml(def_quota_xml);
}
oss << "</USER>";
@ -239,9 +337,6 @@ int User::from_xml(const string& xml)
ObjectXML::free_nodes(content);
content.clear();
// Quotas
rc += quota.from_xml(this);
if (rc != 0)
{
return -1;

View File

@ -793,10 +793,57 @@ int UserPool::authorize(AuthRequest& ar)
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void UserPool::add_extra_xml(ostringstream& oss)
int UserPool::dump(ostringstream& oss, const string& where)
{
string def_quota_xml;
int rc;
string def_quota_xml;
ostringstream cmd;
cmd << "SELECT " << User::table << ".body, "
<< UserQuotas::db_table << ".body"
<< " FROM " << User::table << " LEFT JOIN " << UserQuotas::db_table
<< " ON " << User::table << ".oid=" << UserQuotas::db_table << ".user_oid";
if ( !where.empty() )
{
cmd << " WHERE " << where;
}
cmd << " ORDER BY oid";
oss << "<USER_POOL>";
set_callback(static_cast<Callbackable::Callback>(&UserPool::dump_cb),
static_cast<void *>(&oss));
rc = db->exec(cmd, this);
unset_callback();
oss << Nebula::instance().get_default_user_quota().to_xml(def_quota_xml);
oss << "</USER_POOL>";
return rc;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int UserPool::dump_cb(void * _oss, int num, char **values, char **names)
{
ostringstream * oss;
oss = static_cast<ostringstream *>(_oss);
if ( (!values[0]) || (num != 2) )
{
return -1;
}
*oss << values[0] << values[1];
return 0;
}
/* -------------------------------------------------------------------------- */

31
src/um/UserQuotas.cc Normal file
View File

@ -0,0 +1,31 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs */
/* */
/* 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 "UserQuotas.h"
/* ************************************************************************** */
/* UserQuotas :: Database Access Functions */
/* ************************************************************************** */
const char * UserQuotas::db_table = "user_quotas";
const char * UserQuotas::db_names = "user_oid, body";
const char * UserQuotas::db_oid_column = "user_oid";
const char * UserQuotas::db_bootstrap =
"CREATE TABLE IF NOT EXISTS user_quotas ("
"user_oid INTEGER PRIMARY KEY, body MEDIUMTEXT)";