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

Feature #407: Started adding Sunstone support to chown, chgrp, groups

This commit is contained in:
Hector Sanjuan 2011-06-08 13:50:47 +02:00 committed by Ruben S. Montero
parent e0a6ca1c21
commit f8e64561aa
18 changed files with 755 additions and 549 deletions

View File

@ -17,7 +17,7 @@
require 'OpenNebula'
include OpenNebula
require 'OpenNebulaJSON/ClusterJSON'
require 'OpenNebulaJSON/GroupJSON'
require 'OpenNebulaJSON/HostJSON'
require 'OpenNebulaJSON/ImageJSON'
require 'OpenNebulaJSON/TemplateJSON'

View File

@ -17,16 +17,16 @@
require 'OpenNebulaJSON/JSONUtils'
module OpenNebulaJSON
class ClusterJSON < OpenNebula::Cluster
class GroupJSON < OpenNebula::Group
include JSONUtils
def create(template_json)
cluster_hash = parse_json(template_json,'cluster')
if OpenNebula.is_error?(cluster_hash)
return cluster_hash
group_hash = parse_json(template_json,'group')
if OpenNebula.is_error?(group_hash)
return group_hash
end
self.allocate(cluster_hash['name'])
self.allocate(group_hash['name'])
end
def perform_action(template_json)
@ -36,21 +36,16 @@ module OpenNebulaJSON
end
rc = case action_hash['perform']
when "add_host" then self.add_host(action_hash['params'])
when "remove_host" then self.remove_host(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
when "chown" then self.chown(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
end
def add_host(params=Hash.new)
super(params['host_id'])
end
def remove_host(params=Hash.new)
super(params['host_id'])
def chown(params=Hash.new)
super(params['owner_id'].to_i,-1)
end
end
end

View File

@ -42,19 +42,20 @@ module OpenNebulaJSON
end
rc = case action_hash['perform']
when "disable" then self.disable
when "enable" then self.enable
when "nonpersistent" then self.nonpersistent
when "persistent" then self.persistent
when "publish" then self.publish
when "rm_attr" then self.remove_attr(action_hash['params'])
when "unpublish" then self.unpublish
when "update" then self.update(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
when "disable" then self.disable
when "enable" then self.enable
when "nonpersistent" then self.nonpersistent
when "persistent" then self.persistent
when "publish" then self.publish
when "rm_attr" then self.remove_attr(action_hash['params'])
when "unpublish" then self.unpublish
when "update" then self.update(action_hash['params'])
when "chown" then self.chown(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
end
def update(params=Hash.new)
@ -64,5 +65,9 @@ module OpenNebulaJSON
def remove_attr(params=Hash.new)
super(params['name'])
end
def chown(params=Hash.new)
super(params['owner_id'].to_i,params['group_id'].to_i)
end
end
end

View File

@ -15,6 +15,7 @@
#--------------------------------------------------------------------------- #
module OpenNebulaJSON
require 'json'
module JSONUtils

View File

@ -22,6 +22,6 @@ module OpenNebulaJSON
class VirtualNetworkPoolJSON < OpenNebula::VirtualNetworkPool; include JSONUtils; end
class ImagePoolJSON < OpenNebula::ImagePool; include JSONUtils; end
class TemplatePoolJSON < OpenNebula::TemplatePool; include JSONUtils; end
class ClusterPoolJSON < OpenNebula::ClusterPool; include JSONUtils; end
class GroupPoolJSON < OpenNebula::GroupPool; include JSONUtils; end
class UserPoolJSON < OpenNebula::UserPool; include JSONUtils; end
end

View File

@ -42,16 +42,16 @@ module OpenNebulaJSON
end
rc = case action_hash['perform']
when "publish" then self.publish
when "rm_attr" then self.remove_attr(action_hash['params'])
when "unpublish" then self.unpublish
when "update" then self.update(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
when "publish" then self.publish
when "rm_attr" then self.remove_attr(action_hash['params'])
when "unpublish" then self.unpublish
when "update" then self.update(action_hash['params'])
when "chown" then self.chown(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
end
def update(params=Hash.new)
@ -61,5 +61,9 @@ module OpenNebulaJSON
def remove_attr(params=Hash.new)
super(params['name'])
end
def chown(params=Hash.new)
super(params['owner_id'].to_i,params['group_id'].to_i)
end
end
end

View File

@ -37,17 +37,22 @@ module OpenNebulaJSON
end
rc = case action_hash['perform']
when "passwd" then self.passwd(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
when "passwd" then self.passwd(action_hash['params'])
when "chgrp" then self.chgrp(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
end
def passwd(params=Hash.new)
password = Digest::SHA1.hexdigest(params['password'])
super(password)
end
def chgrp(params=Hash.new)
super(params['group_id'])
end
end
end

View File

@ -49,25 +49,26 @@ module OpenNebulaJSON
end
rc = case action_hash['perform']
when "cancel" then self.cancel
when "deploy" then self.deploy(action_hash['params'])
when "finalize" then self.finalize
when "hold" then self.hold
when "livemigrate" then self.live_migrate(action_hash['params'])
when "migrate" then self.migrate(action_hash['params'])
when "resume" then self.resume
when "release" then self.release
when "stop" then self.stop
when "suspend" then self.suspend
when "restart" then self.restart
when "saveas" then self.save_as(action_hash['params'])
when "shutdown" then self.shutdown
when "resubmit" then self.resubmit
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
when "cancel" then self.cancel
when "deploy" then self.deploy(action_hash['params'])
when "finalize" then self.finalize
when "hold" then self.hold
when "livemigrate" then self.live_migrate(action_hash['params'])
when "migrate" then self.migrate(action_hash['params'])
when "resume" then self.resume
when "release" then self.release
when "stop" then self.stop
when "suspend" then self.suspend
when "restart" then self.restart
when "saveas" then self.save_as(action_hash['params'])
when "shutdown" then self.shutdown
when "resubmit" then self.resubmit
when "chown" then self.chown(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
end
def delete
@ -89,5 +90,9 @@ module OpenNebulaJSON
def save_as(params=Hash.new)
super(params['disk_id'].to_i, params['image_name'])
end
def chown(params=Hash.new)
super(params['owner_id'].to_i,params['group_id'].to_i)
end
end
end

View File

@ -42,13 +42,18 @@ module OpenNebulaJSON
end
rc = case action_hash['perform']
when "publish" then self.publish
when "unpublish" then self.unpublish
else
error_msg = "#{action_hash['perform']} action not " <<
when "publish" then self.publish
when "unpublish" then self.unpublish
when "chown" then self.chown(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
OpenNebula::Error.new(error_msg)
end
end
def chown(params=Hash.new)
super(params['owner_id'].to_i,params['group_id'].to_i)
end
end
end

View File

@ -55,7 +55,7 @@ class SunstoneServer
def get_pool(kind)
user_flag = -2
pool = case kind
when "cluster" then ClusterPoolJSON.new(@client)
when "group" then GroupPoolJSON.new(@client)
when "host" then HostPoolJSON.new(@client)
when "image" then ImagePoolJSON.new(@client, user_flag)
when "template" then TemplatePoolJSON.new(@client, user_flag)
@ -92,7 +92,7 @@ class SunstoneServer
############################################################################
def create_resource(kind, template)
resource = case kind
when "cluster" then ClusterJSON.new(Cluster.build_xml, @client)
when "group" then GroupJSON.new(Group.build_xml, @client)
when "host" then HostJSON.new(Host.build_xml, @client)
when "image" then ImageJSON.new(Image.build_xml, @client)
when "template" then TemplateJSON.new(Template.build_xml, @client)
@ -299,7 +299,7 @@ class SunstoneServer
def retrieve_resource(kind, id)
resource = case kind
when "cluster" then ClusterJSON.new_with_id(id, @client)
when "group" then GroupJSON.new_with_id(id, @client)
when "host" then HostJSON.new_with_id(id, @client)
when "image" then ImageJSON.new_with_id(id, @client)
when "template" then TemplateJSON.new_with_id(id, @client)

View File

@ -177,6 +177,42 @@ var OpenNebula = {
p_pool[0][type] = pool;
return(p_pool);
}
},
"chown": function(params,resource,url_prefix,chgrp){
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var id2 = params.data.extra_param;
var method = "chown";
//if trying to change group, set owner to -1, otherwise set group to -1
var object = chgrp ? {"owner_id": "-1", "group_id": id2} : {"owner_id": id2, "group_id": "-1"};
var action = OpenNebula.Helper.action(method,object);
var request = OpenNebula.Helper.request(resource,method, [id, id2]);
$.ajax({
url: url_prefix + "/" + id + "/action",
type: "POST",
data: JSON.stringify(action),
success: function()
{
if (callback)
{
callback(request);
}
},
error: function(response)
{
if (callback_error)
{
callback_error(request, OpenNebula.Error(response));
}
}
});
},
"chgrp": function(params,resource,url_prefix){
OpenNebula.Helper.chown(params,resource,url_prefix,true);
}
},
@ -725,6 +761,14 @@ var OpenNebula = {
}
}
});
},
"chown" : function(params){
OpenNebula.Helper.chown(params,OpenNebula.Network.resource,"vnet");
},
"chgrp" : function(params){
OpenNebula.Helper.chgrp(params,OpenNebula.Network.resource,"vnet");
}
},
@ -1431,24 +1475,31 @@ var OpenNebula = {
}
}
});
}
},
"chown" : function(params){
OpenNebula.Helper.chown(params,OpenNebula.VM.resource,"vm");
},
"chgrp" : function(params){
OpenNebula.Helper.chgrp(params,OpenNebula.VM.resource,"vm");
}
},
"Cluster": {
"resource": "CLUSTER",
"Group": {
"resource": "GROUP",
"create": function(params)
{
var callback = params.success;
var callback_error = params.error;
var data = params.data;
var resource = OpenNebula.Cluster.resource;
var resource = OpenNebula.Group.resource;
var request = OpenNebula.Helper.request(resource,"create", name);
$.ajax({
url: "/cluster",
url: "/group",
type: "POST",
dataType: "json",
data: JSON.stringify(data),
@ -1474,12 +1525,12 @@ var OpenNebula = {
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var resource = OpenNebula.Cluster.resource;
var resource = OpenNebula.Group.resource;
var request = OpenNebula.Helper.request(resource,"delete", id);
$.ajax({
url: "/cluster/" + id,
url: "/group/" + id,
type: "DELETE",
success: function()
{
@ -1504,11 +1555,11 @@ var OpenNebula = {
var callback_error = params.error;
var timeout = params.timeout || false;
var resource = OpenNebula.Cluster.resource;
var resource = OpenNebula.Group.resource;
var request = OpenNebula.Helper.request(resource,"list");
$.ajax({
url: "/cluster",
url: "/group",
type: "GET",
dataType: "json",
data: {timeout: timeout},
@ -1516,8 +1567,8 @@ var OpenNebula = {
{
if (callback)
{
var cluster_pool = OpenNebula.Helper.pool(resource,response);
callback(request, cluster_pool);
var group_pool = OpenNebula.Helper.pool(resource,response);
callback(request, group_pool);
}
},
error: function(response)
@ -1530,75 +1581,9 @@ var OpenNebula = {
});
},
"addhost": function(params)
"chown": function(params)
{
var callback = params.success;
var callback_error = params.error;
var host_id = params.data.id;
var cluster_id = params.data.extra_param;
var resource = OpenNebula.Cluster.resource;
var method = "add_host";
var action = OpenNebula.Helper.action(method, {
"host_id" : host_id
});
var request = OpenNebula.Helper.request(resource,method, [host_id, cluster_id]);
$.ajax({
url: "/cluster/" + cluster_id + "/action",
type: "POST",
data: JSON.stringify(action),
success: function(response)
{
if (callback)
{
callback(request, response);
}
},
error: function(response)
{
if (callback_error)
{
callback_error(request, OpenNebula.Error(response));
}
}
});
},
"removehost": function(params)
{
var callback = params.success;
var callback_error = params.error;
var host_id = params.data.id;
var cluster_id = params.data.extra_param;
var method = "remove_host";
var action = OpenNebula.Helper.action(method, {
"host_id" : host_id
});
var resource = OpenNebula.Cluster.resource;
var request = OpenNebula.Helper.request(resource,method, [host_id, cluster_id]);
$.ajax({
url: "/cluster/" + cluster_id + "/action",
type: "POST",
data: JSON.stringify(action),
success: function(response)
{
if (callback)
{
callback(request, response);
}
},
error: function(response)
{
if (callback_error)
{
callback_error(request, OpenNebula.Error(response));
}
}
});
OpenNebula.Helper.chown(params,OpenNebula.Group.resource,"group");
}
},
@ -1731,6 +1716,37 @@ var OpenNebula = {
}
}
});
},
"chgrp" : function(params){
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var gid = params.data.extra_param;
var method = "chgrp";
var action = OpenNebula.Helper.action(method, {"group_id": gid});
var request = OpenNebula.Helper.request(OpenNebula.User.resource,method, [id, gid]);
$.ajax({
url: "user/" + id + "/action",
type: "POST",
data: JSON.stringify(action),
success: function()
{
if (callback)
{
callback(request);
}
},
error: function(response)
{
if (callback_error)
{
callback_error(request, OpenNebula.Error(response));
}
}
});
}
},
@ -2127,6 +2143,14 @@ var OpenNebula = {
}
}
});
},
"chown" : function(params){
OpenNebula.Helper.chown(params,OpenNebula.Image.resource,"image");
},
"chgrp" : function(params){
OpenNebula.Helper.chgrp(params,OpenNebula.Image.resource,"image");
}
},
@ -2423,6 +2447,14 @@ var OpenNebula = {
}
}
});
},
"chown" : function(params){
OpenNebula.Helper.chown(params,OpenNebula.Template.resource,"template");
},
"chgrp" : function(params){
OpenNebula.Helper.chgrp(params,OpenNebula.Template.resource,"template");
}
}
}

View File

@ -15,7 +15,7 @@
/* -------------------------------------------------------------------------- */
var HISTORY_LENGTH=40;
var GRAPH_AUTOREFRESH_INTERVAL=10000; //10 secs
var GRAPH_AUTOREFRESH_INTERVAL=100000; //100 secs
var graph1 = {
title : "graph1",
@ -64,8 +64,8 @@ var dashboard_tab_content =
<td class="value_td"><span id="total_hosts"></span><span id="active_hosts" class="green"></span></td>\
</tr>\
<tr>\
<td class="key_td">Clusters</td>\
<td class="value_td"><span id="total_clusters"></span></td>\
<td class="key_td">Groups</td>\
<td class="value_td"><span id="total_groups"></span></td>\
</tr>\
<tr>\
<td class="key_td">VM Templates (total/public)</td>\
@ -101,7 +101,7 @@ var dashboard_tab_content =
<table style="width:100%;"><tr style="vertical-align:middle;"><td style="width:70%">\
<label style="font-weight:bold;width:40px;height:7em;">New:</label>\
<input type="radio" name="quickstart" value="Host.create_dialog">Host</input><br />\
<input type="radio" name="quickstart" value="Cluster.create_dialog">Cluster</input><br />\
<input type="radio" name="quickstart" value="Group.create_dialog">Group</input><br />\
<input type="radio" name="quickstart" value="Template.create_dialog">VM Template</input><br />\
<input type="radio" name="quickstart" value="VM.create_dialog">VM Instance</input><br />\
<input type="radio" name="quickstart" value="Image.create_dialog">Image</input><br />\
@ -273,9 +273,9 @@ function updateDashboard(what,json_info){
$('#total_hosts',db).html(total_hosts+'&nbsp;/&nbsp;');
$('#active_hosts',db).html(active_hosts);
break;
case "clusters":
var total_clusters=json_info.length;
$('#total_clusters',db).html(total_clusters);
case "groups":
var total_groups=json_info.length;
$('#total_groups',db).html(total_groups);
break;
case "vms":
var total_vms=json_info.length;

View File

@ -0,0 +1,277 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
var group_select="";
var group_list_json = {};
var dataTable_groups;
var groups_tab_content =
'<form id="group_form" action="" action="javascript:alert(\'js error!\');">\
<div class="action_blocks">\
</div>\
<table id="datatable_groups" class="display">\
<thead>\
<tr>\
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
<th>ID</th>\
<th>Owner</th>\
<th>Name</th>\
</tr>\
</thead>\
<tbody id="tbodygroups">\
</tbody>\
</table>\
</form>';
var create_group_tmpl =
'<form id="create_group_form" action="">\
<fieldset style="border:none;">\
<div>\
<label for="name">Group name:</label>\
<input type="text" name="name" id="name" /><br />\
</div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_group_submit" value="Group.create">Create</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>';
var group_actions = {
"Group.create" : {
type: "create",
call : OpenNebula.Group.create,
callback : addGroupElement,
error : onError,
notify: true
},
"Group.create_dialog" : {
type: "custom",
call: popUpCreateGroupDialog
},
"Group.list" : {
type: "list",
call: OpenNebula.Group.list,
callback: updateGroupsView,
error: onError,
},
// "Group.showinfo" : {
// type: "custom",
// call: updateGroupInfo
// },
"Group.autorefresh" : {
type: "custom",
call: function () {
OpenNebula.Group.list({timeout: true, success: updateGroupsView,error: onError});
}
},
"Group.refresh" : {
type: "custom",
call: function() {
waitingNodes(dataTable_groups);
Sunstone.runAction("Group.list");
},
callback: function(){},
error: onError,
notify: false
},
"Group.delete" : {
type: "multiple",
call : OpenNebula.Group.delete,
callback : deleteGroupElement,
error : onError,
elements: function() { return getSelectedNodes(dataTable_groups); },
notify:true
},
"Group.chown" : {
type: "multiple",
call : OpenNebula.Group.chown,
callback : updateGroupElement,
elements: function() { return getSelectedNodes(dataTable_groups); },
error : onError,
notify:true
},
}
var group_buttons = {
"Group.refresh" : {
type: "image",
text: "Refresh list",
img: "/images/Refresh-icon.png",
condition: True
},
"Group.create_dialog" : {
type: "create_dialog",
text: "+ New Group",
condition : True
},
"Group.chown" : {
type: "confirm_with_select",
text: "Change group owner",
select: function(){return users_select},
tip: "Select the new group owner:",
condition : True
},
"Group.delete" : {
type: "action",
text: "Delete",
condition : True
}
};
var groups_tab = {
title: 'Groups',
content: groups_tab_content,
buttons: group_buttons,
condition: True
}
Sunstone.addActions(group_actions);
Sunstone.addMainTab('groups_tab',groups_tab);
function groupElementArray(group_json){
var group = group_json.GROUP;
return [ '<input type="checkbox" id="group_'+group.ID+'" name="selected_items" value="'+group.ID+'"/>',
group.ID,
getUserName(group.UID),
group.NAME ];
}
function groupInfoListener(){
$('#tbodygroups tr').live("click",function(e){
//do nothing if we are clicking a checkbox!
if ($(e.target).is('input')) {return true;}
var aData = dataTable_groups.fnGetData(this);
var id = $(aData[0]).val();
Sunstone.runAction("Group.showinfo",id);
return false;
});
}
function updateGroupSelect(){
groups_select = makeSelectOptions(dataTable_groups,1,3,-1,"",-1);
}
function updateGroupElement(request, group_json){
var id = group_json.GROUP.ID;
var element = groupElementArray(group_json);
updateSingleElement(element,dataTable_groups,'#group_'+id);
//No need to update select as all items are in it always
}
function deleteGroupElement(request){
deleteElement(dataTable_groups,'#group_'+req.request.data);
updateGroupSelect();
}
function addGroupElement(request,group_json){
var id = group_json.GROUP.ID;
var element = groupElementArray(group_json);
addElement(element,dataTable_groups);
updateGroupSelect();
}
//updates the list
function updateGroupsView(request, group_list){
group_list_json = group_list;
var group_list_array = [];
$.each(group_list,function(){
group_list_array.push(groupElementArray(this));
});
updateView(group_list_array,dataTable_groups);
updateGroupSelect(group_list);
updateDashboard("groups",group_list);
}
//Prepares the dialog to create
function setupCreateGroupDialog(){
$('div#dialogs').append('<div title="Create group" id="create_group_dialog"></div>');
$('#create_group_dialog').html(create_group_tmpl);
$('#create_group_dialog').dialog({
autoOpen: false,
modal: true,
width: 400
});
$('#create_group_dialog button').button();
$('#create_group_form').submit(function(){
var name=$('#name',this).val();
var group_json = { "group" : { "name" : name }};
Sunstone.runAction("Group.create",group_json);
$('#create_group_dialog').dialog('close');
return false;
});
}
function popUpCreateGroupDialog(){
$('#create_group_dialog').dialog('open');
return false;
}
//Prepares the autorefresh
function setGroupAutorefresh(){
setInterval(function(){
var checked = $('input:checked',dataTable_groups.fnGetNodes());
var filter = $("#datatable_groups_filter input").attr("value");
if (!checked.length && !filter.length){
Sunstone.runAction("Group.autorefresh");
}
},INTERVAL+someTime());
}
$(document).ready(function(){
dataTable_groups = $("#datatable_groups").dataTable({
"bJQueryUI": true,
"bSortClasses": false,
"sPaginationType": "full_numbers",
"bAutoWidth":false,
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0] },
{ "sWidth": "35px", "aTargets": [1] }
]
});
dataTable_groups.fnClearTable();
addElement([
spinner,
'','',''],dataTable_groups);
Sunstone.runAction("Group.list");
setupCreateGroupDialog();
setGroupAutorefresh();
initCheckAllBoxes(dataTable_groups);
tableCheckboxesListener(dataTable_groups);
})

View File

@ -44,7 +44,7 @@ var hosts_tab_content =
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
<th>ID</th>\
<th>Name</th>\
<th>Cluster</th>\
<th>Group</th>\
<th>Running VMs</th>\
<th>CPU Use</th>\
<th>Memory use</th>\
@ -99,123 +99,96 @@ var create_host_tmpl =
</fieldset>\
</form></div>';
var create_cluster_tmpl =
'<form id="create_cluster_form" action="">\
<fieldset style="border:none;">\
<div>\
<label for="name">Cluster name:</label>\
<input type="text" name="name" id="name" /><br />\
</div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_cluster_submit" value="cluster/create">Create</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>';
var hosts_select="";
var clusters_select="";
var host_list_json = {};
var cluster_list_json = {};
var dataTable_hosts;
//Setup actions
var host_actions = {
"Host.create" : {
type: "create",
call : OpenNebula.Host.create,
callback : addHostElement,
error : onError,
notify: true
},
"Host.create_dialog" : {
type: "custom",
call: popUpCreateHostDialog
},
//Custom below
//~ "Host.list" : {
//~ type: "list",
//~ call: OpenNebula.Host.list,
//~ callback: updateHostsView,
//~ error: onError,
//~ notify:False
//~ },
"Host.show" : {
type: "single",
call: OpenNebula.Host.show,
callback: updateHostElement,
error: onError
},
"Host.showinfo" : {
type: "single",
call: OpenNebula.Host.show,
callback: updateHostInfo,
error: onError
},
"Host.refresh" : {
type: "custom",
call: function(){
waitingNodes(dataTable_hosts);
Sunstone.runAction("Host.list");
},
callback: function(){},
error: onError,
notify:false
},
"Host.autorefresh" : {
type: "custom",
call : function() {
OpenNebula.Host.list({timeout: true, success: updateHostsView,error: onError});
}
},
"Host.enable" : {
type: "multiple",
call : OpenNebula.Host.enable,
callback : function (req) {
Sunstone.runAction("Host.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_hosts); },
error : onError,
notify: true
},
"Host.disable" : {
type: "multiple",
call : OpenNebula.Host.disable,
callback : function (req) {
Sunstone.runAction("Host.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_hosts); },
error : onError,
notify:true
},
"Host.delete" : {
type: "multiple",
call : OpenNebula.Host.delete,
callback : deleteHostElement,
elements: function() { return getSelectedNodes(dataTable_hosts); },
error : onError,
notify:true
},
"Host.list" : {
type: "custom",
call : function() {
OpenNebula.Host.list({success: updateHostsView, error: onError});
OpenNebula.Cluster.list({success: updateClustersView, error: onError});
}
},
"Host.create" : {
type: "create",
call : OpenNebula.Host.create,
callback : addHostElement,
error : onError,
notify: true
},
"Host.create_dialog" : {
type: "custom",
call: popUpCreateHostDialog
},
"Host.list" : {
type: "list",
call: OpenNebula.Host.list,
callback: updateHostsView,
error: onError,
notify: false
},
"Host.show" : {
type: "single",
call: OpenNebula.Host.show,
callback: updateHostElement,
error: onError
},
"Host.showinfo" : {
type: "single",
call: OpenNebula.Host.show,
callback: updateHostInfo,
error: onError
},
"Host.refresh" : {
type: "custom",
call: function(){
waitingNodes(dataTable_hosts);
Sunstone.runAction("Host.list");
},
callback: function(){},
error: onError,
notify:false
},
"Host.autorefresh" : {
type: "custom",
call : function() {
OpenNebula.Host.list({timeout: true, success: updateHostsView,error: onError});
}
},
"Host.enable" : {
type: "multiple",
call : OpenNebula.Host.enable,
callback : function (req) {
Sunstone.runAction("Host.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_hosts); },
error : onError,
notify: true
},
"Host.disable" : {
type: "multiple",
call : OpenNebula.Host.disable,
callback : function (req) {
Sunstone.runAction("Host.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_hosts); },
error : onError,
notify:true
},
"Host.delete" : {
type: "multiple",
call : OpenNebula.Host.delete,
callback : deleteHostElement,
elements: function() { return getSelectedNodes(dataTable_hosts); },
error : onError,
notify:true
},
"Host.monitor" : {
type: "monitor",
@ -236,127 +209,38 @@ var host_actions = {
plot_global_graph(response,info);
},
error: onError
},
"Cluster.create" : {
type: "create",
call : OpenNebula.Cluster.create,
callback : function(){
Sunstone.runAction("Cluster.list");
},
error : onError,
notify: true
},
"Cluster.create_dialog" : {
type: "custom",
call: popUpCreateClusterDialog
},
"Cluster.list" : {
type: "list",
call: OpenNebula.Cluster.list,
callback: updateClustersView,
error: onError,
},
"Cluster.autorefresh" : {
type: "custom",
call: function () {
OpenNebula.Cluster.list({timeout: true, success: updateClustersView,error: onError});
}
},
"Cluster.delete" : {
type: "single",
call : OpenNebula.Cluster.delete,
callback : function(){
//OpenNebula.Cluster.list({success: updateClustersView, error: onError});
Sunstone.runAction("Cluster.list");
},
error : onError,
notify:true
},
"Cluster.addhost" : {
type: "multiple",
call : OpenNebula.Cluster.addhost,
callback : function(req){
Sunstone.runAction("Host.show",req.request.data);
},
elements: function() { return getSelectedNodes(dataTable_hosts); },
error : onError,
notify:true
},
"Cluster.removehost" : {
type: "multiple",
call : OpenNebula.Cluster.removehost,
callback : deleteHostElement,
elements: function() { return getSelectedNodes(dataTable_hosts); },
error : onError,
notify:true
}
};
}
};
var host_buttons = {
"Host.refresh" : {
type: "image",
text: "Refresh list",
img: "/images/Refresh-icon.png",
condition: True
"Host.refresh" : {
type: "image",
text: "Refresh list",
img: "/images/Refresh-icon.png",
condition: True
},
"Host.create_dialog" : {
type: "create_dialog",
text: "+ New",
condition :True
},
"Host.enable" : {
type: "action",
text: "Enable",
condition : True
},
"Host.disable" : {
type: "action",
text: "Disable",
condition : True
},
"Cluster.create_dialog" : {
type: "create_dialog",
text: "+ New Cluster",
condition : True
},
"Cluster.delete" : {
type: "confirm_with_select",
text: "Delete cluster",
select: function(){return clusters_select},
tip: "Select the cluster you want to remove",
condition : True
},
"action_list" : { //Special button
type: "select",
actions: { "Cluster.addhost": {
type: "confirm_with_select",
text: "Add host to cluster",
select: function(){return clusters_select;},
tip: "Select the cluster in which you would like to place the hosts",
condition: True
},
"Cluster.removehost" : {
type: "action",
text: "Remove host from cluster",
condition: True
}},
condition : True
},
"Host.delete" : {
type: "action",
text: "Delete host",
condition : True
}
};
"Host.create_dialog" : {
type: "create_dialog",
text: "+ New",
condition :True
},
"Host.enable" : {
type: "action",
text: "Enable",
condition : True
},
"Host.disable" : {
type: "action",
text: "Disable",
condition : True
},
"Host.delete" : {
type: "action",
text: "Delete host",
condition : True
}
};
var host_info_panel = {
"host_info_tab" : {
title: "Host information",
@ -375,7 +259,7 @@ var host_info_panel = {
var hosts_tab = {
title: 'Hosts &amp; Clusters',
title: 'Hosts',
content: hosts_tab_content,
buttons: host_buttons,
condition: True
@ -390,12 +274,12 @@ Sunstone.addInfoPanel("host_info_panel",host_info_panel);
//Creates an array to be added to the dataTable from the JSON of a host.
function hostElementArray(host_json){
var host = host_json.HOST;
var host = host_json.HOST;
//Calculate some values
var acpu = parseInt(host.HOST_SHARE.MAX_CPU);
if (!acpu) {acpu=100};
acpu = acpu - parseInt(host.HOST_SHARE.CPU_USAGE);
if (!acpu) {acpu=100};
acpu = acpu - parseInt(host.HOST_SHARE.CPU_USAGE);
var total_mem = parseInt(host.HOST_SHARE.MAX_MEM);
var free_mem = parseInt(host.HOST_SHARE.FREE_MEM);
@ -432,101 +316,81 @@ function hostElementArray(host_json){
return [ '<input type="checkbox" id="host_'+host.ID+'" name="selected_items" value="'+host.ID+'"/>',
host.ID,
host.NAME,
host.CLUSTER,
host.HOST_SHARE.RUNNING_VMS, //rvm
pb_cpu,
pb_mem,
OpenNebula.Helper.resource_state("host_simple",host.STATE) ];
host.ID,
host.NAME,
getGroupName(host.GID),
host.HOST_SHARE.RUNNING_VMS, //rvm
pb_cpu,
pb_mem,
OpenNebula.Helper.resource_state("host_simple",host.STATE) ];
}
//Listen to clicks on the tds of the tables and shows the info dialogs.
function hostInfoListener(){
$('#tbodyhosts tr').live("click",function(e){
$('#tbodyhosts tr').live("click",function(e){
//do nothing if we are clicking a checkbox!
if ($(e.target).is('input')) {return true;}
//do nothing if we are clicking a checkbox!
if ($(e.target).is('input')) {return true;}
popDialogLoading();
var aData = dataTable_hosts.fnGetData(this);
var id = $(aData[0]).val();
var aData = dataTable_hosts.fnGetData(this);
var id = $(aData[0]).val();
Sunstone.runAction("Host.showinfo",id);
return false;
});
return false;
});
}
//updates the host select by refreshing the options in it
function updateHostSelect(){
hosts_select = makeSelectOptions(dataTable_hosts,1,2,7,"DISABLED",-1);
}
//updates the cluster select by refreshing the options in it
function updateClusterSelect(cluster_list){
//manual, as there is not dataTable for it
clusters_select="<option value=\"\">Select a cluster</option>";
$.each(cluster_list, function(){
clusters_select += "<option value=\""+this.CLUSTER.ID+"\">"+this.CLUSTER.NAME+"</option>";
});
}
//callback for an action affecting a host element
function updateHostElement(request, host_json){
var id = host_json.HOST.ID;
var element = hostElementArray(host_json);
updateSingleElement(element,dataTable_hosts,'#host_'+id);
var id = host_json.HOST.ID;
var element = hostElementArray(host_json);
updateSingleElement(element,dataTable_hosts,'#host_'+id);
updateHostSelect();
}
//callback for actions deleting a host element
function deleteHostElement(req){
deleteElement(dataTable_hosts,'#host_'+req.request.data);
deleteElement(dataTable_hosts,'#host_'+req.request.data);
updateHostSelect();
}
//call back for actions creating a host element
function addHostElement(request,host_json){
var id = host_json.HOST.ID;
var element = hostElementArray(host_json);
addElement(element,dataTable_hosts);
var element = hostElementArray(host_json);
addElement(element,dataTable_hosts);
updateHostSelect();
}
//callback to update the list of hosts.
function updateHostsView (request,host_list){
host_list_json = host_list;
var host_list_array = []
host_list_json = host_list;
var host_list_array = [];
$.each(host_list,function(){
$.each(host_list,function(){
//Grab table data from the host_list
host_list_array.push(hostElementArray(this));
});
host_list_array.push(hostElementArray(this));
});
updateView(host_list_array,dataTable_hosts);
updateHostSelect();
updateView(host_list_array,dataTable_hosts);
updateHostSelect();
//dependency with the dashboard plugin
updateDashboard("hosts",host_list_json);
}
//updates the list of clusters
function updateClustersView(request, cluster_list){
cluster_list_json = cluster_list;
updateClusterSelect(cluster_list);
updateDashboard("clusters",cluster_list);
updateDashboard("hosts",host_list_json);
}
//Updates the host info panel tab's content and pops it up
function updateHostInfo(request,host){
var host_info = host.HOST;
var host_info = host.HOST;
//Information tab
var info_tab = {
title : "Host information",
content :
'<table id="info_host_table" class="info_table">\
'<table id="info_host_table" class="info_table">\
<thead>\
<tr><th colspan="2">Host information - '+host_info.NAME+'</th></tr>\
</thead>\
@ -539,8 +403,8 @@ function updateHostInfo(request,host){
<td class="value_td">'+OpenNebula.Helper.resource_state("host",host_info.STATE)+'</td>\
</tr>\
<tr>\
<td class="key_td">Cluster</td>\
<td class="value_td">'+host_info.CLUSTER+'</td>\
<td class="key_td">Group</td>\
<td class="value_td">'+host_info.GID+'</td>\
</tr>\
<tr>\
<td class="key_td">IM MAD</td>\
@ -628,84 +492,47 @@ function setupCreateHostDialog(){
$('#create_host_dialog button').button();
//Handle the form submission
$('#create_host_form').submit(function(){
$('#create_host_form').submit(function(){
if (!($('#name',this).val().length)){
notifyError("Host name missing!");
return false;
}
var host_json = { "host": { "name": $('#name',this).val(),
"tm_mad": $('#tm_mad :selected',this).val(),
"vm_mad": $('#vmm_mad :selected',this).val(),
"im_mad": $('#im_mad :selected',this).val()}}
var host_json = { "host": { "name": $('#name',this).val(),
"tm_mad": $('#tm_mad :selected',this).val(),
"vm_mad": $('#vmm_mad :selected',this).val(),
"im_mad": $('#im_mad :selected',this).val()}}
//Create the OpenNebula.Host.
//If it's successfull we refresh the list.
//Create the OpenNebula.Host.
//If it's successfull we refresh the list.
Sunstone.runAction("Host.create",host_json);
//OpenNebula.Host.create({data: host_json, success: addHostElement, error: onError});
$('#create_host_dialog').dialog('close');
return false;
});
//OpenNebula.Host.create({data: host_json, success: addHostElement, error: onError});
$('#create_host_dialog').dialog('close');
return false;
});
}
//Prepares the dialog to create a cluster
function setupCreateClusterDialog(){
$('div#dialogs').append('<div title="Create cluster" id="create_cluster_dialog"></div>');
$('#create_cluster_dialog').html(create_cluster_tmpl);
$('#create_cluster_dialog').dialog({
autoOpen: false,
modal: true,
width: 400
});
$('#create_cluster_dialog button').button();
$('#create_cluster_form').submit(function(){
var name=$('#name',this).val();
var cluster_json = { "cluster" : { "name" : name }};
Sunstone.runAction("Cluster.create",cluster_json);
$('#create_cluster_dialog').dialog('close');
return false;
});
}
//Open creation dialogs
function popUpCreateHostDialog(){
$('#create_host_dialog').dialog('open');
return false;
}
function popUpCreateClusterDialog(){
$('#create_cluster_dialog').dialog('open');
return false;
}
//Prepares the autorefresh for hosts
function setHostAutorefresh() {
setInterval(function(){
var checked = $('input:checked',dataTable_hosts.fnGetNodes());
var filter = $("#datatable_hosts_filter input").attr("value");
if (!checked.length && !filter.length){
Sunstone.runAction("Host.autorefresh");
}
},INTERVAL+someTime());
}
//Prepares the autorefresh for clusters
function setClusterAutorefresh(){
setInterval(function(){
Sunstone.runAction("Cluster.autorefresh");
},INTERVAL+someTime());
var checked = $('input:checked',dataTable_hosts.fnGetNodes());
var filter = $("#datatable_hosts_filter input").attr("value");
if (!checked.length && !filter.length){
Sunstone.runAction("Host.autorefresh");
}
},INTERVAL+someTime());
}
//This is executed after the sunstone.js ready() is run.
//Here we can basicly init the host datatable, preload it
//and add specific listeners
$(document).ready(function(){
//prepare host datatable
dataTable_hosts = $("#datatable_hosts").dataTable({
"bJQueryUI": true,
@ -726,16 +553,12 @@ $(document).ready(function(){
spinner,
'','','','','','',''],dataTable_hosts);
Sunstone.runAction("Host.list");
Sunstone.runAction("Cluster.list");
setupCreateHostDialog();
setupCreateClusterDialog();
setHostAutorefresh();
setClusterAutorefresh();
initCheckAllBoxes(dataTable_hosts);
tableCheckboxesListener(dataTable_hosts);
hostInfoListener();
});

View File

@ -15,6 +15,9 @@
/* -------------------------------------------------------------------------- */
/*Users tab plugin*/
var user_list_json = {};
var dataTable_users;
var users_select="";
var users_tab_content =
'<form id="user_form" action="" action="javascript:alert(\'js error!\');">\
@ -51,9 +54,6 @@ var create_user_tmpl =
</fieldset>\
</form>';
var user_list_json = {};
var dataTable_users;
var user_actions = {
"User.create" : {
type: "create",
@ -149,34 +149,41 @@ function userElementArray(user_json){
}
function updateUserSelect(){
users_select = makeSelectOptions(dataTable_users,1,2,-1,"",-1);
}
// Callback to refresh a single element from the dataTable
function updateUserElement(request, user_json){
var id = user_json.USER.ID;
var element = userElementArray(user_json);
updateSingleElement(element,dataTable_users,'#user_'+id);
var id = user_json.USER.ID;
var element = userElementArray(user_json);
updateSingleElement(element,dataTable_users,'#user_'+id);
}
// Callback to delete a single element from the dataTable
function deleteUserElement(req){
deleteElement(dataTable_users,'#user_'+req.request.data);
deleteElement(dataTable_users,'#user_'+req.request.data);
updateUserSelect();
}
// Callback to add a single user element
function addUserElement(request,user_json){
var element = userElementArray(user_json);
addElement(element,dataTable_users);
updateUserSelect();
}
// Callback to update the list of users
function updateUsersView(request,users_list){
user_list_json = users_list;
var user_list_array = [];
user_list_json = users_list;
var user_list_array = [];
$.each(user_list_json,function(){
user_list_array.push(userElementArray(this));
});
updateView(user_list_array,dataTable_users);
updateDashboard("users",user_list_json);
$.each(user_list_json,function(){
user_list_array.push(userElementArray(this));
});
updateView(user_list_array,dataTable_users);
updateDashboard("users",user_list_json);
updateUserSelect();
}
// Prepare the user creation dialog
@ -218,16 +225,15 @@ function popUpCreateUserDialog(){
// Prepare the autorefresh of the list
function setUserAutorefresh(){
setInterval(function(){
var checked = $('input:checked',dataTable_users.fnGetNodes());
var checked = $('input:checked',dataTable_users.fnGetNodes());
var filter = $("#datatable_users_filter input").attr("value");
if (!checked.length && !filter.length){
if (!checked.length && !filter.length){
Sunstone.runAction("User.autorefresh");
}
}
},INTERVAL+someTime());
}
$(document).ready(function(){
//if we are not oneadmin, our tab will not even be in the DOM.
if (uid==0) {
dataTable_users = $("#datatable_users").dataTable({
@ -236,21 +242,21 @@ $(document).ready(function(){
"sPaginationType": "full_numbers",
"bAutoWidth":false,
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0] },
{ "sWidth": "35px", "aTargets": [1] }
]
});
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0] },
{ "sWidth": "35px", "aTargets": [1] }
]
});
dataTable_users.fnClearTable();
addElement([
spinner,
'',''],dataTable_users);
Sunstone.runAction("User.list");
setupCreateUserDialog();
setUserAutorefresh();
initCheckAllBoxes(dataTable_users);
tableCheckboxesListener(dataTable_users);
}

View File

@ -134,34 +134,34 @@ var vnet_actions = {
error: onError,
notify: true
},
"Network.create_dialog" : {
type: "custom",
call: popUpCreateVnetDialog
},
"Network.list" : {
type: "list",
call: OpenNebula.Network.list,
callback: updateVNetworksView,
error: onError
},
"Network.show" : {
type: "single",
call: OpenNebula.Network.show,
callback: updateVNetworkElement,
error: onError
},
"Network.showinfo" : {
type: "single",
call: OpenNebula.Network.show,
callback: updateVNetworkInfo,
error: onError
},
"Network.refresh" : {
type: "custom",
call: function(){
@ -169,14 +169,14 @@ var vnet_actions = {
Sunstone.runAction("Network.list");
}
},
"Network.autorefresh" : {
type: "custom",
call: function() {
OpenNebula.Network.list({timeout: true, success: updateVNetworksView, error: onError});
}
},
"Network.publish" : {
type: "multiple",
call: OpenNebula.Network.publish,
@ -187,7 +187,7 @@ var vnet_actions = {
error: onError,
notify: true
},
"Network.unpublish" : {
type: "multiple",
call: OpenNebula.Network.unpublish,
@ -198,7 +198,7 @@ var vnet_actions = {
error: onError,
notify: true
},
"Network.delete" : {
type: "multiple",
call: OpenNebula.Network.delete,
@ -206,8 +206,29 @@ var vnet_actions = {
elements: function() { return getSelectedNodes(dataTable_vNetworks); },
error: onError,
notify: true
},
"Network.chown" : {
type: "multiple",
call: OpenNebula.Network.chown,
callback: function (req) {
Sunstone.runAction("Network.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_vNetworks); },
error:onError,
notify: true
},
"Network.chgrp" : {
type: "multiple",
call: OpenNebula.Network.chown,
callback: function (req) {
Sunstone.runAction("Network.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_vNetworks); },
error:onError,
notify: true
}
}
@ -236,6 +257,22 @@ var vnet_buttons = {
text: "Unpublish",
condition: True
},
"Network.chown" : {
type: "confirm_with_select",
text: "Change owner",
select: function() {return users_select;},
tip: "Select the new owner:",
condition: True
},
"Network.chgrp" : {
type: "confirm_with_select",
text: "Change group",
select: function() {return groups_select;},
tip: "Select the new group:",
condition: True
},
"Network.delete" : {
type: "action",
@ -381,7 +418,7 @@ function updateVNetworkInfo(request,vn){
<thead>\
<tr><th colspan="2">Leases information</th></tr>\
</thead>'+
prettyPrintJSON(vn_info.LEASES.LEASE)+
prettyPrintJSON(vn_info.TEMPLATE.LEASES)+
'</table>';
}

View File

@ -383,9 +383,9 @@ function getUserName(uid){
var user = uid;
if (typeof(dataTable_users) == "undefined") {
return user;
}
}
var nodes = dataTable_users.fnGetData();
$.each(nodes,function(){
if (uid == this[1]) {
user = this[2];
@ -396,6 +396,11 @@ function getUserName(uid){
}
//Todo
function getGroupName(gid){
return gid;
}
//Replaces all class"tip" divs with an information icon that
//displays the tip information on mouseover.
@ -460,12 +465,15 @@ function makeSelectOptions(dataTable,
$.each(nodes,function(){
var id = this[id_col];
var name = this[name_col];
var status = this[status_col];
var status;
if (status_col >= 0) {
status = this[status_col];
}
var user = user_col > 0 ? this[user_col] : false;
var isMine = user ? (username == user) || (uid == user) : true;
if ((status != status_bad) || isMine ){
if (status_col < 0 || (status != status_bad) || isMine ){
select +='<option value="'+id+'">'+name+'</option>';
}
});

View File

@ -26,8 +26,11 @@
<script type="text/javascript" src="/js/layout.js"></script>
<script type="text/javascript" src="/js/sunstone.js"></script>
<script type="text/javascript" src="/js/sunstone-util.js"></script>
<!--Base plugins-->
<script type="text/javascript" src="/js/plugins/dashboard-tab.js"></script>
<script type="text/javascript" src="/js/plugins/hosts-tab.js"></script>
<script type="text/javascript" src="/js/plugins/groups-tab.js"></script>
<script type="text/javascript" src="/js/plugins/templates-tab.js"></script>
<script type="text/javascript" src="/js/plugins/vms-tab.js"></script>
<script type="text/javascript" src="/js/plugins/vnets-tab.js"></script>