1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-25 02:50:08 +03:00

Feature #3471: Remove group resource providers

This commit is contained in:
Carlos Martín 2015-01-21 12:24:44 +01:00
parent 258fb5e607
commit 509300f1da
17 changed files with 1 additions and 1163 deletions

View File

@ -44,12 +44,6 @@ public:
*/
static const int NONE_CLUSTER_ID;
/**
* Special ID to refer to all OpenNebula resources, from any cluster
* or in cluster none (* in ACL rules).
*/
static const int ALL_RESOURCES;
/* ---------------------------------------------------------------------- */
/* Methods for DB management */
/* ---------------------------------------------------------------------- */

View File

@ -75,26 +75,6 @@ public:
return del_collection_id(id);
}
/**
* Adds a resource provider
* @param zone_id ID of the zone
* @param cluster_id ID of the cluster
* @param error_msg Returns the error reason, if any
*
* @return 0 on success
*/
int add_resource_provider(int zone_id, int cluster_id, string& error_msg);
/**
* Deletes a resource provider
* @param zone_id ID of the zone
* @param cluster_id ID of the cluster
* @param error_msg Returns the error reason, if any
*
* @return 0 on success
*/
int del_resource_provider(int zone_id, int cluster_id, string& error_msg);
/**
* Object quotas, provides set and check interface
*/
@ -146,12 +126,6 @@ private:
delete obj_template;
};
// *************************************************************************
// Attributes (Private)
// *************************************************************************
set<pair<int,int> > providers;
// *************************************************************************
// DataBase implementation (Private)
// *************************************************************************

View File

@ -66,82 +66,6 @@ public:
RequestAttributes& att);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class GroupEditProvider : public Request
{
public:
void request_execute(xmlrpc_c::paramList const& _paramList,
RequestAttributes& att);
protected:
GroupEditProvider( const string& method_name,
const string& help,
const string& params,
bool _check_obj_exist)
:Request(method_name,params,help),
check_obj_exist(_check_obj_exist)
{
Nebula& nd = Nebula::instance();
pool = nd.get_gpool();
clpool = nd.get_clpool();
zonepool = nd.get_zonepool();
aclm = nd.get_aclm();
local_zone_id = nd.get_zone_id();
auth_object = PoolObjectSQL::GROUP;
auth_op = AuthRequest::ADMIN;
};
ZonePool* zonepool;
ClusterPool* clpool;
AclManager* aclm;
bool check_obj_exist;
int local_zone_id;
virtual int edit_resource_provider(
Group* group, int zone_id, int cluster_id, string& error_msg) = 0;
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class GroupAddProvider : public GroupEditProvider
{
public:
GroupAddProvider():
GroupEditProvider("GroupAddProvider",
"Adds a resource provider to the group",
"A:siii",
true){};
~GroupAddProvider(){};
int edit_resource_provider(
Group* group, int zone_id, int cluster_id, string& error_msg);
};
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
class GroupDelProvider : public GroupEditProvider
{
public:
GroupDelProvider():
GroupEditProvider("GroupDelProvider",
"Deletes a resource provider from the group",
"A:siii",
false){};
~GroupDelProvider(){};
int edit_resource_provider(
Group* group, int zone_id, int cluster_id, string& error_msg);
};
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -14,14 +14,6 @@
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="RESOURCE_PROVIDER" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ZONE_ID" type="xs:integer"/>
<xs:element name="CLUSTER_ID" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="DATASTORE_QUOTA" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>

View File

@ -18,14 +18,6 @@
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="RESOURCE_PROVIDER" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="ZONE_ID" type="xs:integer"/>
<xs:element name="CLUSTER_ID" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>

View File

@ -294,22 +294,6 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
group_hash = group.to_hash
providers = group_hash['GROUP']['RESOURCE_PROVIDER']
if(providers != nil)
puts
CLIHelper.print_header(str_h1 % "RESOURCE PROVIDERS", false)
CLIHelper::ShowTable.new(nil, self) do
column :"ZONE", "", :right, :size=>7 do |d|
d['ZONE_ID']
end
column :"CLUSTER", "", :right, :size=>7 do |d|
d['CLUSTER_ID'] == '10' ? 'ALL' : d['CLUSTER_ID']
end
end.show([providers].flatten, {})
end
default_quotas = nil
group.each('/GROUP/DEFAULT_GROUP_QUOTAS') { |elem|

View File

@ -61,14 +61,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do
helper.list_to_id(arg)
end
set :format, :clusterid, OpenNebulaHelper.rname_to_id_desc("CLUSTER") do |arg|
OpenNebulaHelper.rname_to_id(arg, "CLUSTER")
end
set :format, :zoneid, OpenNebulaHelper.rname_to_id_desc("ZONE") do |arg|
OpenNebulaHelper.rname_to_id(arg, "ZONE")
end
########################################################################
# Commands
########################################################################
@ -239,33 +231,4 @@ cmd=CommandParser::CmdParser.new(ARGV) do
exit 0
end
add_provider_desc = <<-EOT.unindent
Adds a resource provider (cluster of a zone) to the given group.
clusterid can be set to ALL
EOT
command :add_provider, add_provider_desc, [:range, :groupid_list], :zoneid, :clusterid do
if args[2] and args[2].class != Fixnum and args[2].upcase == "ALL"
args[2]=10
end
helper.perform_actions(args[0],options,"resource provider added") do |obj|
obj.add_provider(args[1].to_i, args[2].to_i)
end
end
del_provider_desc = <<-EOT.unindent
Deletes a resource provider (cluster of a zone) from the given group
clusterid can be set to ALL
EOT
command :del_provider, del_provider_desc, [:range, :groupid_list], :zoneid, :clusterid do
if args[2] and args[2].class != Fixnum and args[2].upcase == "ALL"
args[2]=10
end
helper.perform_actions(args[0],options,"resource provider deleted") do |obj|
obj.del_provider(args[1].to_i, args[2].to_i)
end
end
end

View File

@ -28,7 +28,6 @@
const string ClusterPool::NONE_CLUSTER_NAME = "";
const int ClusterPool::NONE_CLUSTER_ID = -1;
const int ClusterPool::ALL_RESOURCES = 10;
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -216,8 +216,6 @@ string& Group::to_xml_extended(string& xml, bool extended) const
string collection_xml;
string template_xml;
set<pair<int,int> >::const_iterator it;
ObjectCollection::to_xml(collection_xml);
oss <<
@ -227,15 +225,6 @@ string& Group::to_xml_extended(string& xml, bool extended) const
obj_template->to_xml(template_xml) <<
collection_xml;
for (it = providers.begin(); it != providers.end(); it++)
{
oss <<
"<RESOURCE_PROVIDER>" <<
"<ZONE_ID>" << it->first << "</ZONE_ID>" <<
"<CLUSTER_ID>" << it->second << "</CLUSTER_ID>" <<
"</RESOURCE_PROVIDER>";
}
if (extended)
{
string quota_xml;
@ -300,25 +289,6 @@ int Group::from_xml(const string& xml)
ObjectXML::free_nodes(content);
content.clear();
// Set of resource providers
ObjectXML::get_nodes("/GROUP/RESOURCE_PROVIDER", content);
for (it = content.begin(); it != content.end(); it++)
{
ObjectXML tmp_xml(*it);
int zone_id, cluster_id;
rc += tmp_xml.xpath(zone_id, "/RESOURCE_PROVIDER/ZONE_ID", -1);
rc += tmp_xml.xpath(cluster_id, "/RESOURCE_PROVIDER/CLUSTER_ID", -1);
providers.insert(pair<int,int>(zone_id, cluster_id));
}
ObjectXML::free_nodes(content);
content.clear();
if (rc != 0)
{
return -1;
@ -326,147 +296,3 @@ int Group::from_xml(const string& xml)
return 0;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Group::add_resource_provider(int zone_id, int cluster_id, string& error_msg)
{
AclManager* aclm = Nebula::instance().get_aclm();
int rc = 0;
long long mask_prefix;
pair<set<pair<int, int> >::iterator,bool> ret;
ret = providers.insert(pair<int,int>(zone_id, cluster_id));
if( !ret.second )
{
error_msg = "Resource provider is already assigned to this group";
return -1;
}
if (cluster_id == ClusterPool::ALL_RESOURCES)
{
mask_prefix = AclRule::ALL_ID;
}
else
{
mask_prefix = AclRule::CLUSTER_ID | cluster_id;
}
// @<gid> HOST/%<cid> MANAGE #<zone>
rc += aclm->add_rule(
AclRule::GROUP_ID |
oid,
mask_prefix |
PoolObjectSQL::HOST,
AuthRequest::MANAGE,
AclRule::INDIVIDUAL_ID |
zone_id,
error_msg);
if (rc < 0)
{
NebulaLog::log("GROUP",Log::ERROR,error_msg);
}
// @<gid> DATASTORE+NET/%<cid> USE #<zone>
rc += aclm->add_rule(
AclRule::GROUP_ID |
oid,
mask_prefix |
PoolObjectSQL::DATASTORE |
PoolObjectSQL::NET,
AuthRequest::USE,
AclRule::INDIVIDUAL_ID |
zone_id,
error_msg);
if (rc < 0)
{
NebulaLog::log("GROUP",Log::ERROR,error_msg);
}
return 0;
}
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
int Group::del_resource_provider(int zone_id, int cluster_id, string& error_msg)
{
AclManager* aclm = Nebula::instance().get_aclm();
int rc = 0;
long long mask_prefix;
if( providers.erase(pair<int,int>(zone_id, cluster_id)) != 1 )
{
error_msg = "Resource provider is not assigned to this group";
return -1;
}
if (cluster_id == ClusterPool::ALL_RESOURCES)
{
mask_prefix = AclRule::ALL_ID;
}
else
{
mask_prefix = AclRule::CLUSTER_ID | cluster_id;
}
// @<gid> HOST/%<cid> MANAGE #<zid>
rc += aclm->del_rule(
AclRule::GROUP_ID |
oid,
mask_prefix |
PoolObjectSQL::HOST,
AuthRequest::MANAGE,
AclRule::INDIVIDUAL_ID |
zone_id,
error_msg);
if (rc < 0)
{
NebulaLog::log("GROUP",Log::ERROR,error_msg);
}
// @<gid> DATASTORE+NET/%<cid> USE #<zid>
rc += aclm->del_rule(
AclRule::GROUP_ID |
oid,
mask_prefix |
PoolObjectSQL::DATASTORE |
PoolObjectSQL::NET,
AuthRequest::USE,
AclRule::INDIVIDUAL_ID |
zone_id,
error_msg);
if (rc < 0)
{
NebulaLog::log("GROUP",Log::ERROR,error_msg);
}
return 0;
}

View File

@ -77,14 +77,6 @@ GroupPool::GroupPool(SqlDB * db,
goto error_groups;
}
group = get(rc, true);
group->add_resource_provider(Nebula::instance().get_zone_id(), ClusterPool::ALL_RESOURCES, error_str);
update(group);
group->unlock();
set_update_lastOID(99);
}

View File

@ -32,8 +32,6 @@ public class Group extends PoolElement{
private static final String INFO = METHOD_PREFIX + "info";
private static final String DELETE = METHOD_PREFIX + "delete";
private static final String QUOTA = METHOD_PREFIX + "quota";
private static final String ADD_PROVIDER = METHOD_PREFIX + "addprovider";
private static final String DEL_PROVIDER = METHOD_PREFIX + "delprovider";
private static final String UPDATE = METHOD_PREFIX + "update";
/**
@ -111,36 +109,6 @@ public class Group extends PoolElement{
return client.call(QUOTA, id, quota_template);
}
/**
* Adds a resource provider to this group
*
* @param client XML-RPC Client.
* @param id The group id.
* @param zoneId The zone id.
* @param clusterId The cluster id.
* @return A encapsulated response.
*/
public static OneResponse addProvider(Client client, int id,
int zoneId, int clusterId)
{
return client.call(ADD_PROVIDER, id, zoneId, clusterId);
}
/**
* Deletes a resource provider from this group
*
* @param client XML-RPC Client.
* @param id The group id.
* @param zoneId The zone id.
* @param clusterId The cluster id.
* @return A encapsulated response.
*/
public static OneResponse delProvider(Client client, int id,
int zoneId, int clusterId)
{
return client.call(DEL_PROVIDER, id, zoneId, clusterId);
}
/**
* Replaces the template contents.
*
@ -194,30 +162,6 @@ public class Group extends PoolElement{
return setQuota(client, id, quota_template);
}
/**
* Adds a resource provider to this group
*
* @param zoneId The zone id.
* @param clusterId The cluster id.
* @return A encapsulated response.
*/
public OneResponse addProvider(int zoneId, int clusterId)
{
return addProvider(client, id, zoneId, clusterId);
}
/**
* Deletes a resource provider from this group
*
* @param zoneId The zone id.
* @param clusterId The cluster id.
* @return A encapsulated response.
*/
public OneResponse delProvider(int zoneId, int clusterId)
{
return delProvider(client, id, zoneId, clusterId);
}
/**
* Replaces the template contents.
*

View File

@ -28,9 +28,7 @@ module OpenNebula
:allocate => "group.allocate",
:update => "group.update",
:delete => "group.delete",
:quota => "group.quota",
:add_provider => "group.addprovider",
:del_provider => "group.delprovider"
:quota => "group.quota"
}
# Flag for requesting connected user's group info
@ -38,7 +36,6 @@ module OpenNebula
# Default resource ACL's for group users (create)
GROUP_DEFAULT_ACLS = "VM+IMAGE+TEMPLATE+DOCUMENT+SECGROUP"
ALL_CLUSTERS_IN_ZONE = 10
# The default view for group and group admins, must be defined in
# sunstone_views.yaml
@ -82,9 +79,6 @@ module OpenNebula
# group_hash[:name] the group name
# group_hash[:group_admin] the admin user definition hash, see def
# create_admin_user function description for details.
# group_hash[:resource_providers]
# group_hash[:resource_providers][:zone_id]
# group_hash[:resource_providers][:cluster_id]
# group_hash[:views] Array of sunstone view names, to be stored
# in SUNSTONE_VIEWS
# group_hash[:default_view] Default sunstone view name, to be stored
@ -107,17 +101,6 @@ module OpenNebula
rc = self.allocate(group_hash[:name])
return rc if OpenNebula.is_error?(rc)
# Handle resource providers
group_hash[:resource_providers].each { |rp|
next if rp[:zone_id].nil? && rp[:cluster_id].nil?
if rp[:cluster_id].class == String && rp[:cluster_id] == "ALL"
add_provider(rp[:zone_id],ALL_CLUSTERS_IN_ZONE)
else
add_provider(rp[:zone_id],rp[:cluster_id])
end
} if !group_hash[:resource_providers].nil?
# Set group ACLs to create resources
rc, msg = create_default_acls(group_hash[:resources])
@ -210,26 +193,6 @@ module OpenNebula
return rc
end
# Adds a resource provider to this group
# @param zone_id [Integer] Zone ID
# @param cluster_id [Integer] Cluster ID
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def add_provider(zone_id, cluster_id)
return call(GROUP_METHODS[:add_provider], @pe_id, zone_id.to_i, cluster_id.to_i)
end
# Deletes a resource provider from this group
# @param zone_id [Integer] Zone ID
# @param cluster_id [Integer] Cluster ID
#
# @return [nil, OpenNebula::Error] nil in case of success, Error
# otherwise
def del_provider(zone_id, cluster_id)
return call(GROUP_METHODS[:del_provider], @pe_id, zone_id.to_i, cluster_id.to_i)
end
# ---------------------------------------------------------------------
# Helpers to get information
# ---------------------------------------------------------------------

View File

@ -484,30 +484,22 @@ void RequestManager::register_xml_methods()
xmlrpc_c::method * group_allocate_pt;
xmlrpc_c::method * group_update_pt;
xmlrpc_c::method * group_delete_pt;
xmlrpc_c::method * group_add_provider_pt;
xmlrpc_c::method * group_del_provider_pt;
if (nebula.is_federation_slave())
{
group_allocate_pt = new RequestManagerProxy("one.group.allocate");
group_delete_pt = new RequestManagerProxy("one.group.delete");
group_add_provider_pt = new RequestManagerProxy("one.group.addprovider");
group_del_provider_pt = new RequestManagerProxy("one.group.delprovider");
group_update_pt = new RequestManagerProxy("one.group.update");
}
else
{
group_allocate_pt = new GroupAllocate();
group_delete_pt = new GroupDelete();
group_add_provider_pt = new GroupAddProvider();
group_del_provider_pt = new GroupDelProvider();
group_update_pt = new GroupUpdateTemplate();
}
xmlrpc_c::methodPtr group_allocate(group_allocate_pt);
xmlrpc_c::methodPtr group_delete(group_delete_pt);
xmlrpc_c::methodPtr group_add_provider(group_add_provider_pt);
xmlrpc_c::methodPtr group_del_provider(group_del_provider_pt);
xmlrpc_c::methodPtr group_update(group_update_pt);
xmlrpc_c::methodPtr group_info(new GroupInfo());
@ -520,8 +512,6 @@ void RequestManager::register_xml_methods()
RequestManagerRegistry.addMethod("one.group.delete", group_delete);
RequestManagerRegistry.addMethod("one.group.info", group_info);
RequestManagerRegistry.addMethod("one.group.quota", group_set_quota);
RequestManagerRegistry.addMethod("one.group.addprovider",group_add_provider);
RequestManagerRegistry.addMethod("one.group.delprovider",group_del_provider);
RequestManagerRegistry.addMethod("one.group.update", group_update);
RequestManagerRegistry.addMethod("one.grouppool.info", grouppool_info);

View File

@ -81,145 +81,3 @@ void GroupSetQuota::
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void GroupEditProvider::request_execute(
xmlrpc_c::paramList const& paramList,
RequestAttributes& att)
{
int group_id = xmlrpc_c::value_int(paramList.getInt(1));
int zone_id = xmlrpc_c::value_int(paramList.getInt(2));
int cluster_id = xmlrpc_c::value_int(paramList.getInt(3));
PoolObjectAuth group_perms;
PoolObjectAuth zone_perms;
PoolObjectAuth cluster_perms;
string group_name;
string zone_name;
string cluster_name;
string error_str;
Group* group;
int rc;
bool zone_exists = false;
bool cluster_exists = false;
// -------------------------------------------------------------------------
// Authorize the action
// -------------------------------------------------------------------------
rc = get_info(pool, group_id, PoolObjectSQL::GROUP,
att, group_perms, group_name, true);
if ( rc == -1 )
{
return;
}
rc = get_info(zonepool, zone_id, PoolObjectSQL::ZONE, att, zone_perms,
zone_name, false);
zone_exists = (rc == 0);
if ( rc == -1 && check_obj_exist )
{
failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::ZONE),
zone_id), att);
return;
}
// TODO: cluster must exist in target zone, this code only checks locally
if (cluster_id != ClusterPool::ALL_RESOURCES && zone_id == local_zone_id)
{
rc = get_info(clpool, cluster_id, PoolObjectSQL::CLUSTER, att,
cluster_perms, cluster_name, false);
cluster_exists = (rc == 0);
if ( rc == -1 && check_obj_exist )
{
failure_response(NO_EXISTS, get_error(object_name(PoolObjectSQL::CLUSTER),
cluster_id), att);
return;
}
}
if ( att.uid != 0 )
{
AuthRequest ar(att.uid, att.group_ids);
ar.add_auth(AuthRequest::ADMIN, group_perms); // ADMIN GROUP
if (zone_exists)
{
ar.add_auth(AuthRequest::ADMIN, zone_perms); // ADMIN ZONE
}
if (cluster_exists)
{
ar.add_auth(AuthRequest::ADMIN, cluster_perms); // ADMIN CLUSTER
}
if (UserPool::authorize(ar) == -1)
{
failure_response(AUTHORIZATION,
authorization_error(ar.message, att),
att);
return;
}
}
group = static_cast<GroupPool*>(pool)->get(group_id, true);
if ( group == 0 )
{
failure_response(NO_EXISTS,
get_error(object_name(auth_object),group_id),
att);
return;
}
rc = edit_resource_provider(group, zone_id, cluster_id, error_str);
if (rc == 0)
{
pool->update(group);
}
group->unlock();
if (rc != 0)
{
failure_response(INTERNAL,
request_error("Cannot edit resources", error_str),
att);
return;
}
success_response(group_id, att);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int GroupAddProvider::edit_resource_provider(
Group* group, int zone_id, int cluster_id, string& error_msg)
{
return group->add_resource_provider(zone_id, cluster_id, error_msg);
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int GroupDelProvider::edit_resource_provider(
Group* group, int zone_id, int cluster_id, string& error_msg)
{
return group->del_resource_provider(zone_id, cluster_id, error_msg);
}

View File

@ -39,10 +39,6 @@ module OpenNebulaJSON
when "chown" then self.chown(action_hash['params'])
when "update" then self.update_json(action_hash['params'])
when "set_quota" then self.set_quota(action_hash['params'])
when "add_provider" then
self.add_provider_json(action_hash['params'])
when "del_provider" then
self.del_provider_json(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
@ -63,13 +59,5 @@ module OpenNebulaJSON
quota_template = template_to_str(quota_json)
super(quota_template)
end
def add_provider_json(params=Hash.new)
add_provider(params['zone_id'].to_i, params['cluster_id'].to_i)
end
def del_provider_json(params=Hash.new)
del_provider(params['zone_id'].to_i, params['cluster_id'].to_i)
end
end
end

View File

@ -1141,14 +1141,6 @@ var OpenNebula = {
},
"accounting" : function(params){
OpenNebula.Action.monitor(params,OpenNebula.Group.resource,false);
},
"add_provider" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,OpenNebula.Group.resource,"add_provider",action_obj);
},
"del_provider" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,OpenNebula.Group.resource,"del_provider",action_obj);
}
},

View File

@ -55,7 +55,6 @@ function create_group_tmpl(dialog_name){
<div class="columns large-7">\
<dl class="tabs right-info-tabs text-center right" data-tab>\
<dd class="active"><a href="#resource_views"><i class="fa fa-eye"></i><br>'+tr("Views")+'</a></dd>\
<dd><a href="#resource_providers"><i class="fa fa-cloud"></i><br>'+tr("Resources")+'</a></dd>\
<dd><a href="#administrators"><i class="fa fa-upload"></i><br>'+tr("Admin")+'</a></dd>\
<dd><a href="#resource_creation"><i class="fa fa-folder-open"></i><br>'+tr("Permissions")+'</a></dd>\
</dl>\
@ -90,19 +89,6 @@ function create_group_tmpl(dialog_name){
+'</div>\
</div>\
</div>\
<div id="resource_providers" class="content">\
<div class="row">\
<div class="large-12 columns">\
<h5>' + tr("Zones") +'</h5>\
</div>\
</div>\
<div class="row">\
<div class="large-12 columns">\
<dl class="tabs" id="group_zones_tabs" data-tab></dl>\
<div class="tabs-content group_zones_tabs_content"></div>\
</div>\
</div>\
</div>\
<div id="administrators" class=" content">\
<div class="row">\
<div class="large-6 columns">\
@ -333,63 +319,6 @@ var group_actions = {
//plot_graph(response,'#group_acct_tabTab','group_acct_', info);
},
error: onError
},
"Group.add_provider_action" : {
type: "single",
call: OpenNebula.Group.add_provider,
callback: function(request) {
Sunstone.runAction('Group.show',request.request.data[0][0]);
},
error: onError
},
"Group.del_provider_action" : {
type: "single",
call: OpenNebula.Group.del_provider,
callback: function(request) {
Sunstone.runAction('Group.show',request.request.data[0][0]);
},
error: onError
},
"Group.add_provider" : {
type: "multiple",
call: function(params){
var cluster = params.data.extra_param;
var group = params.data.id;
extra_param = {
"zone_id" : 0,
"cluster_id" : cluster
}
Sunstone.runAction("Group.add_provider_action", group, extra_param);
},
callback: function(request) {
Sunstone.runAction('Group.show',request.request.data[0]);
},
elements: groupElements
},
"Group.del_provider" : {
type: "multiple",
call: function(params){
var cluster = params.data.extra_param;
var group = params.data.id;
extra_param = {
"zone_id" : 0,
"cluster_id" : cluster
}
Sunstone.runAction("Group.del_provider_action", group, extra_param);
},
callback: function(request) {
Sunstone.runAction('Group.show',request.request.data[0]);
},
elements: groupElements
}
}
@ -588,66 +517,6 @@ function updateGroupsView(request, group_list, quotas_hash){
$(".total_groups").text(group_list.length);
}
function fromJSONtoProvidersTable(group_info){
providers_array=group_info.RESOURCE_PROVIDER
var str = ""
if (!providers_array){ return "";}
if (!$.isArray(providers_array))
{
var tmp_array = new Array();
tmp_array[0] = providers_array;
providers_array = tmp_array;
}
$.each(providers_array, function(index, provider){
var cluster_id = (provider.CLUSTER_ID == "10") ? tr("All") : provider.CLUSTER_ID;
str +=
'<tr>\
<td>' + provider.ZONE_ID + '</td>\
<td>' + cluster_id + '</td>\
<td>\
<div id="div_minus_rp" class="text-right">\
<a id="div_minus_rp_a_'+provider.ZONE_ID+'" class="cluster_id_'+cluster_id+' group_id_'+group_info.ID+'" href="#"><i class="fa fa-trash-o"/></a>\
</div>\
</td>\
</tr>';
});
$("#div_minus_rp").die();
// Listener for key,value pair remove action
$("#div_minus_rp").live("click", function() {
// Remove div_minus from the id
zone_id = this.firstElementChild.id.substring(15,this.firstElementChild.id.length);
var list_of_classes = this.firstElementChild.className.split(" ");
$.each(list_of_classes, function(index, value) {
if (value.match(/^cluster_id_/))
{
cluster_id=value.substring(11,value.length);
}
else
{
if (value.match(/^group_id_/))
{
group_id=value.substring(9,value.length);
}
}
});
extra_param = {
"zone_id" : zone_id,
"cluster_id" : (cluster_id == "All") ? 10 : cluster_id
}
Sunstone.runAction("Group.del_provider_action", group_id, extra_param);
});
return str;
}
function updateGroupInfo(request,group){
var info = group.GROUP;
@ -700,33 +569,6 @@ function updateGroupInfo(request,group){
content : quotas_html
};
var providers_tab = {
title : tr("Providers"),
icon: "fa-th",
content :
'<div class="">\
<div class="large-6 columns">\
<table id="info_user_table" class="dataTable extended_table">\
<thead>\
<tr>\
<th>' + tr("Zone ID") + '</th>\
<th>' + tr("Cluster ID") + '</th>\
<th class="text-right">\
<button id="add_rp_button" class="button tiny success radius" >\
<i class="fa fa-plus-circle"></i>\
</button>\
</th>\
</tr>\
</thead>\
<tbody>' +
fromJSONtoProvidersTable(info) +
'</tbody>\
</table>\
</div>\
</div>'
};
var accounting_tab = {
title: tr("Accounting"),
icon: "fa-bar-chart-o",
@ -736,7 +578,6 @@ function updateGroupInfo(request,group){
Sunstone.updateInfoPanelTab("group_info_panel","group_info_tab",info_tab);
Sunstone.updateInfoPanelTab("group_info_panel","group_quotas_tab",quotas_tab);
Sunstone.updateInfoPanelTab("group_info_panel","group_providers_tab",providers_tab);
Sunstone.updateInfoPanelTab("group_info_panel","group_accounting_tab",accounting_tab);
if (Config.isFeatureEnabled("showback")) {
@ -758,8 +599,6 @@ function updateGroupInfo(request,group){
$("#add_rp_button", $("#group_info_panel")).click(function(){
initUpdateGroupDialog();
$("a[href=#resource_providers]", $update_group_dialog).click();
return false;
});
@ -774,244 +613,6 @@ function updateGroupInfo(request,group){
"Group");
}
function setup_group_resource_tab_content(zone_id, zone_section, str_zone_tab_id, str_datatable_id, selected_group_clusters, group) {
// Show the clusters dataTable when the radio button is selected
$("input[name='"+str_zone_tab_id+"']", zone_section).change(function(){
if ($("input[name='"+str_zone_tab_id+"']:checked", zone_section).val() == "cluster") {
$("div.group_cluster_select", zone_section).show();
}
else {
$("div.group_cluster_select", zone_section).hide();
}
});
if (zone_id == 0 && !group)
{
$('#'+str_zone_tab_id+'resources_all', zone_section).click();
}
else
{
$('#'+str_zone_tab_id+'resources_none', zone_section).click();
}
var dataTable_group_clusters = $('#'+str_datatable_id, zone_section).dataTable({
"iDisplayLength": 4,
"sDom" : '<"H">t<"F"p>',
"bAutoWidth":false,
"bSortClasses" : false,
"bDeferRender": true,
"aoColumnDefs": [
{ "sWidth": "35px", "aTargets": [0,1] },
{ "bVisible": false, "aTargets": []}
]
});
// Retrieve the clusters to fill the datatable
update_datatable_group_clusters(dataTable_group_clusters, zone_id, str_zone_tab_id, group);
$('#'+str_zone_tab_id+'_search', zone_section).keyup(function(){
dataTable_group_clusters.fnFilter( $(this).val() );
})
dataTable_group_clusters.fnSort( [ [1,config['user_config']['table_order']] ] );
$('#'+str_datatable_id + ' tbody', zone_section).delegate("tr", "click", function(e){
var aData = dataTable_group_clusters.fnGetData(this);
if (!aData){
return true;
}
var cluster_id = aData[1];
if ($.isEmptyObject(selected_group_clusters[zone_id])) {
$('#you_selected_group_clusters'+str_zone_tab_id, zone_section).show();
$("#select_group_clusters"+str_zone_tab_id, zone_section).hide();
}
if(!$("td:first", this).hasClass('markrowchecked'))
{
$('input.check_item', this).attr('checked','checked');
selected_group_clusters[zone_id][cluster_id] = this;
$(this).children().each(function(){$(this).addClass('markrowchecked');});
if ($('#tag_cluster_'+aData[1], $('.selected_group_clusters', zone_section)).length == 0 ) {
$('.selected_group_clusters', zone_section).append('<span id="tag_cluster_'+aData[1]+'" class="radius label">'+aData[2]+' <span class="fa fa-times blue"></span></span> ');
}
}
else
{
$('input.check_item', this).removeAttr('checked');
delete selected_group_clusters[zone_id][cluster_id];
$(this).children().each(function(){$(this).removeClass('markrowchecked');});
$('.selected_group_clusters span#tag_cluster_'+cluster_id, zone_section).remove();
}
if ($.isEmptyObject(selected_group_clusters[zone_id])) {
$('#you_selected_group_clusters'+str_zone_tab_id, zone_section).hide();
$('#select_group_clusters'+str_zone_tab_id, zone_section).show();
}
$('.alert-box', $('.group_cluster_select')).hide();
return true;
});
$( '#' +str_zone_tab_id+'Tab .fa-times' ).live( "click", function() {
$(this).parent().remove();
var id = $(this).parent().attr("ID");
var cluster_id=id.substring(12,id.length);
$('td', selected_group_clusters[zone_id][cluster_id]).removeClass('markrowchecked');
$('input.check_item', selected_group_clusters[zone_id][cluster_id]).removeAttr('checked');
delete selected_group_clusters[zone_id][cluster_id];
if ($.isEmptyObject(selected_group_clusters[zone_id])) {
$('#you_selected_group_clusters'+str_zone_tab_id, zone_section).hide();
$('#select_group_clusters'+str_zone_tab_id, zone_section).show();
}
});
setupTips(zone_section);
}
function generate_group_resource_tab_content(str_zone_tab_id, str_datatable_id, zone_id, group){
var html =
'<div class="row">\
<div class="large-12 columns">\
<p class="subheader">' + tr("Assign physical resources") + '\
&emsp;<span class="tip">'+tr("For each OpenNebula Zone, you can assign cluster resources (set of physical hosts, datastores and virtual networks) to this group.")+'</span>\
</p>\
</div>\
</div>\
<div class="row">\
<div class="large-12 columns">\
<input type="radio" name="'+str_zone_tab_id+'" id="'+str_zone_tab_id+'resources_all" value="all"><label for="'+str_zone_tab_id+'resources_all">'+tr("All")+'</label>\
<input type="radio" name="'+str_zone_tab_id+'" id="'+str_zone_tab_id+'resources_cluster" value="cluster"><label for="'+str_zone_tab_id+'resources_cluster">'+tr("Select clusters")+'</label>\
<input type="radio" name="'+str_zone_tab_id+'" id="'+str_zone_tab_id+'resources_none" value="none"><label for="'+str_zone_tab_id+'resources_none">'+tr("None")+'</label>\
</div>\
</div>\
<div class="row">\
<div class="large-12 columns">\
<div id="req_type" class="group_cluster_select hidden">\
<div class="row collapse ">\
<div class="large-9 columns">\
<button id="refresh_group_clusters_table_button_class'+str_zone_tab_id+'" type="button" class="refresh button small radius secondary"><i class="fa fa-refresh" /></button>\
</div>\
<div class="large-3 columns">\
<input id="'+str_zone_tab_id+'_search" class="search" type="text" placeholder="'+tr("Search")+'"/>\
</div>\
</div>\
<table id="'+str_datatable_id+'" class="datatable twelve">\
<thead>\
<tr>\
<th></th>\
<th>' + tr("ID") + '</th>\
<th>' + tr("Name") + '</th>\
<th>' + tr("Hosts") + '</th>\
<th>' + tr("VNets") + '</th>\
<th>' + tr("Datastores") + '</th>\
</tr>\
</thead>\
<tbody id="tbodyclusters">\
</tbody>\
</table>\
<br>\
<div class="selected_group_clusters">\
<span id="select_group_clusters'+str_zone_tab_id+'" class="radius secondary label">'+tr("Please select one or more clusters from the list")+'</span> \
<span id="you_selected_group_clusters'+str_zone_tab_id+'" class="radius secondary label hidden">'+tr("You selected the following clusters:")+'</span> \
</div>\
<br>\
</div\
</div>\
</div>';
$("#refresh_group_clusters_table_button_class"+str_zone_tab_id).die();
$("#refresh_group_clusters_table_button_class"+str_zone_tab_id).live('click', function(){
update_datatable_group_clusters(
$('table[id='+str_datatable_id+']').dataTable(),
zone_id, str_zone_tab_id, group);
});
return html;
}
// TODO: Refactor? same function in templates-tab.js
function update_datatable_group_clusters(datatable, zone_id, str_zone_tab_id, group) {
OpenNebula.Cluster.list_in_zone({
data:{zone_id:zone_id},
timeout: true,
success: function (request, obj_list){
var obj_list_array = [];
$.each(obj_list,function(){
//Grab table data from the obj_list
obj_list_array.push(clusterElementArray(this));
});
updateView(obj_list_array, datatable);
if (group && group.RESOURCE_PROVIDER)
{
var rows = datatable.fnGetNodes();
providers_array = group.RESOURCE_PROVIDER;
if (!$.isArray(providers_array))
{
providers_array = [providers_array];
}
$('#'+str_zone_tab_id+'resources_none').click();
$.each(providers_array, function(index, provider){
if (provider.ZONE_ID==zone_id)
{
for(var j=0;j<rows.length;j++)
{
var current_row = $(rows[j]);
var row_cluster_id = $(rows[j]).find("td:eq(1)").html();
if (provider.CLUSTER_ID == row_cluster_id)
{
current_row.click();
}
}
if (provider.CLUSTER_ID == "10")
$('#'+str_zone_tab_id+'resources_all').click();
else
$('#'+str_zone_tab_id+'resources_cluster').click();
}
});
}
}
});
};
var add_resource_tab = function(zone_id, zone_name, dialog, selected_group_clusters, group) {
var str_zone_tab_id = dialog.attr('id') + '_zone' + zone_id;
var str_datatable_id = dialog.attr('id') + '_datatable_group_clusters_zone_' + zone_id;
selected_group_clusters[zone_id] = {};
// Append the new div containing the tab and add the tab to the list
var html_tab_content = '<div id="'+str_zone_tab_id+'Tab" class="content">'+
generate_group_resource_tab_content(str_zone_tab_id, str_datatable_id, zone_id, group) +
'</div>'
$(html_tab_content).appendTo($(".group_zones_tabs_content", dialog));
var a = $("<dd>\
<a id='zone_tab"+str_zone_tab_id+"' href='#"+str_zone_tab_id+"Tab'>"+zone_name+"</a>\
</dd>").appendTo($("dl#group_zones_tabs", dialog));
// TODOO
//$(document).foundationTabs("set_tab", a);
$("dl#group_zones_tabs", dialog).children("dd").first().children("a").click();
var zone_section = $('#' +str_zone_tab_id+'Tab', dialog);
setup_group_resource_tab_content(zone_id, zone_section, str_zone_tab_id, str_datatable_id, selected_group_clusters, group);
};
function disableAdminUser(dialog){
$('#username',dialog).attr('disabled','disabled');
$('#pass',dialog).attr('disabled','disabled');
@ -1089,21 +690,6 @@ function setupCreateGroupDialog(){
$("#group_res_net", dialog).prop("checked", false);
$("#group_admin_res_net", dialog).prop("checked", false);
var selected_group_clusters = {};
OpenNebula.Zone.list({
timeout: true,
success: function (request, obj_list){
$.each(obj_list,function(){
add_resource_tab(this.ZONE.ID,
this.ZONE.NAME,
dialog,
selected_group_clusters);
});
},
error: onError
});
$('#create_group_form',dialog).submit(function(){
var name = $('#name',this).val();
@ -1128,33 +714,6 @@ function setupCreateGroupDialog(){
group_json["group"]["group_admin"] = user_json["user"];
}
group_json['group']['resource_providers'] = [];
$.each(selected_group_clusters, function(zone_id, zone_clusters) {
var str_zone_tab_id = dialog.attr('id') + '_zone' + zone_id;
var resource_selection = $("input[name='"+str_zone_tab_id+"']:checked", dialog).val();
switch (resource_selection){
case "all":
// 10 is the special ID for ALL, see ClusterPool.h
group_json['group']['resource_providers'].push(
{"zone_id" : zone_id, "cluster_id" : 10}
);
break;
case "cluster":
$.each(selected_group_clusters[zone_id], function(key, value) {
group_json['group']['resource_providers'].push(
{"zone_id" : zone_id, "cluster_id" : key}
);
});
break;
default: // "none"
}
});
var resources = "";
var separator = "";
@ -1268,23 +827,6 @@ function popUpUpdateGroupDialog(group, dialog)
});
}
var selected_group_clusters = {};
OpenNebula.Zone.list({
timeout: true,
success: function (request, obj_list){
$.each(obj_list,function(){
add_resource_tab(this.ZONE.ID,
this.ZONE.NAME,
dialog,
selected_group_clusters,
group);
});
},
error: onError
});
$(dialog).off("click", 'button#update_group_submit');
$(dialog).on("click", 'button#update_group_submit', function(){
@ -1308,85 +850,6 @@ function popUpUpdateGroupDialog(group, dialog)
Sunstone.runAction("Group.update_template",group.ID,template_str);
}
// Update Resource Providers
//-------------------------------------
var old_resource_providers = group.RESOURCE_PROVIDER;
if (!old_resource_providers) {
old_resource_providers = new Array();
} else if (!$.isArray(old_resource_providers)) {
old_resource_providers = [old_resource_providers];
}
var new_resource_providers = [];
$.each(selected_group_clusters, function(zone_id, zone_clusters) {
var str_zone_tab_id = dialog.attr('id') + '_zone' + zone_id;
var resource_selection = $("input[name='"+str_zone_tab_id+"']:checked", dialog).val();
switch (resource_selection){
case "all":
// 10 is the special ID for ALL, see ClusterPool.h
new_resource_providers.push(
{"zone_id" : zone_id, "cluster_id" : 10}
);
break;
case "cluster":
$.each(selected_group_clusters[zone_id], function(key, value) {
new_resource_providers.push(
{"zone_id" : zone_id, "cluster_id" : key}
);
});
break;
default: // "none"
}
});
$.each(old_resource_providers, function(index, old_res_provider){
found = false;
$.each(new_resource_providers, function(index, new_res_provider){
found = (old_res_provider.ZONE_ID == new_res_provider.zone_id &&
old_res_provider.CLUSTER_ID == new_res_provider.cluster_id);
return !found;
});
if (!found) {
var extra_param = {
"zone_id" : old_res_provider.ZONE_ID,
"cluster_id" : old_res_provider.CLUSTER_ID
};
Sunstone.runAction("Group.del_provider_action",
group.ID,
extra_param);
}
});
$.each(new_resource_providers, function(index, new_res_provider){
found = false;
$.each(old_resource_providers, function(index, old_res_provider){
found = (old_res_provider.ZONE_ID == new_res_provider.zone_id &&
old_res_provider.CLUSTER_ID == new_res_provider.cluster_id);
return !found;
});
if (!found) {
var extra_param = new_res_provider;
Sunstone.runAction("Group.add_provider_action",
group.ID,
extra_param);
}
});
// Close the dialog
//-------------------------------------