1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-02-05 21:57:24 +03:00

Merge branch 'feature-407rm'

This commit is contained in:
Ruben S. Montero 2011-06-13 23:05:23 +02:00
commit 75abcefb4d
24 changed files with 3572 additions and 3432 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)
end
end
end

View File

@ -42,27 +42,32 @@ 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)
super(params['name'], params['value'])
super(params['template_raw'])
end
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,24 +42,23 @@ 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
end
def update(params=Hash.new)
super(params['name'], params['value'])
when "publish" then self.publish
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 remove_attr(params=Hash.new)
super(params['name'])
def update(params=Hash.new)
super(params['template_raw'])
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)
@ -87,12 +87,25 @@ class SunstoneServer
end
end
############################################################################
#
############################################################################
def get_template(kind,id)
resource = retrieve_resource(kind,id)
if OpenNebula.is_error?(resource)
return [404, resource.to_json]
else
template_str = resource.template_str(true)
return [200, {:template => template_str}.to_json]
end
end
############################################################################
#
############################################################################
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 +312,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

@ -235,19 +235,19 @@ div.tip span.man_icon {
display:inline-block!important;
}
span.tipspan {
position: fixed;
display:block;
padding:4px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
border: 1px solid #353735;
margin-left:2px;
margin-right:5px;
background-color: white;
span.tipspan,div.full_info {
position: fixed;
display:block;
padding:4px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
border: 1px solid #353735;
margin-left:2px;
margin-right:5px;
background-color: white;
color: #353735;
font-size:10px;
font-size:10px;
}
.vm_section input {
float:none;

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));
}
}
});
}
},
@ -1767,7 +1783,71 @@ var OpenNebula = {
}
});
},
"fetch_template" : function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var method = "fetch_template";
var resource = OpenNebula.Image.resource;
var request = OpenNebula.Helper.request(resource,method, id);
$.ajax({
url: "/image/" + id + "/template",
type: "GET",
dataType:"json",
success: function(response)
{
if (callback)
{
callback(request,response);
}
},
error: function(response)
{
if(callback_error)
{
callback_error(request, OpenNebula.Error(response));
}
}
});
},
"update": function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var template_raw = params.data.extra_param;
var template_obj = {"template_raw": template_raw}
var method = "update";
var action = OpenNebula.Helper.action(method, template_obj);
var resource = OpenNebula.Image.resource;
var request = OpenNebula.Helper.request(resource,method, [id, template_obj]);
$.ajax({
url: "/image/" + 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));
}
}
});
},
"delete": function(params)
{
var callback = params.success;
@ -1858,82 +1938,6 @@ var OpenNebula = {
}
});
},
"addattr": function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var name = params.data.name;
var value = params.data.value;
var method = "update";
var action = OpenNebula.Helper.action(method, {
"name" : name,
"value" : value
});
var resource = OpenNebula.Image.resource;
var request = OpenNebula.Helper.request(resource,method, [id, name, value]);
$.ajax({
url: "/image/" + 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));
}
}
});
},
"rmattr": function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var name = params.data.name;
var value = params.data.value;
var method = "rm_attr";
var action = OpenNebula.Helper.action(method, {
"name" : name
});
var resource = OpenNebula.Image.resource;
var request = OpenNebula.Helper.request(resource,method, [id, name]);
$.ajax({
url: "/image/" + 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));
}
}
});
},
"enable": function(params)
{
var callback = params.success;
@ -2127,6 +2131,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");
}
},
@ -2164,95 +2176,49 @@ var OpenNebula = {
});
},
"addattr" : function(params)
"fetch_template" : function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var name = params.data.name;
var value = params.data.value;
var method = "update";
var action = OpenNebula.Helper.action(method, {
"name" : name,
"value" : value
});
var resource = OpenNebula.Template.resource;
var request = OpenNebula.Helper.request(resource,method, [id, name, value]);
var method = "fetch_template";
var resource = OpenNebula.Template.resource;
var request = OpenNebula.Helper.request(resource,method, id);
$.ajax({
url: "/template/" + id + "/action",
type: "POST",
data: JSON.stringify(action),
url: "/template/" + id + "/template",
type: "GET",
dataType:"json",
success: function(response)
{
if (callback)
{
callback(request, response);
callback(request,response);
}
},
error: function(response)
{
if (callback_error)
if(callback_error)
{
callback_error(request, OpenNebula.Error(response));
}
}
});
});
},
"update" : function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var name = params.data.name;
var value = params.data.value;
var template_raw = params.data.extra_param;
var template_obj = {"template_raw": template_raw}
var method = "update";
var action = OpenNebula.Helper.action(method, {
"name" : name,
"value" : value
});
var action = OpenNebula.Helper.action(method, template_obj);
var resource = OpenNebula.Template.resource;
var request = OpenNebula.Helper.request(resource,method, [id, name, value]);
$.ajax({
url: "/template/" + 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));
}
}
});
},
"rmattr" : function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var name = params.data.name;
var value = params.data.value;
var method = "rm_attr";
var action = OpenNebula.Helper.action(method, {
"name" : name
});
var resource = OpenNebula.Template.resource;
var request = OpenNebula.Helper.request(resource,method, [id, name]);
var request = OpenNebula.Helper.request(resource,method, [id, template_obj]);
$.ajax({
url: "/template/" + id + "/action",
@ -2274,6 +2240,7 @@ var OpenNebula = {
}
});
},
"publish" : function(params)
{
var callback = params.success;
@ -2423,6 +2390,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 />\
@ -184,23 +184,26 @@ function plot_global_graph(data,info){
};
var options = {
legend : { show : true,
noColumns: labels_arr.length,
container: $('#'+id+'_legend')},
xaxis : { mode: "time",
timeformat: "%h:%M"
},
legend : {
show : true,
noColumns: labels_arr.length,
container: $('#'+id+'_legend')
},
xaxis : {
mode: "time",
timeformat: "%h:%M"
},
yaxis : { labelWidth: 40 }
}
switch (id){
case "graph3":
case "graph5":
options["yaxis"]["tickFormatter"] = function(val,axis) { return humanize_size(val); }
options["yaxis"]["tickFormatter"] = function(val,axis) {
return humanize_size(val);
}
}
$.plot($('#'+id+'_graph'),series,options);
}
@ -273,9 +276,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,276 @@
/* -------------------------------------------------------------------------- */
/* 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

@ -33,8 +33,7 @@ var host_graphs = [
]
var hosts_tab_content =
var hosts_tab_content =
'<form id="form_hosts" action="javascript:alert(\'js errors?!\')">\
<div class="action_blocks">\
</div>\
@ -44,7 +43,6 @@ 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>Running VMs</th>\
<th>CPU Use</th>\
<th>Memory use</th>\
@ -65,157 +63,130 @@ var create_host_tmpl =
<h3>Drivers</h3>\
<fieldset>\
<div class="manager clear" id="vmm_mads">\
<label>Virtualization Manager:</label>\
<select id="vmm_mad" name="vmm">\
<option value="vmm_kvm">KVM</option>\
<option value="vmm_xen">XEN</option>\
<option value="vmm_ec2">EC2</option>\
<option value="vmm_dummy">Dummy</option>\
</select>\
<label>Virtualization Manager:</label>\
<select id="vmm_mad" name="vmm">\
<option value="vmm_kvm">KVM</option>\
<option value="vmm_xen">XEN</option>\
<option value="vmm_ec2">EC2</option>\
<option value="vmm_dummy">Dummy</option>\
</select>\
</div>\
<div class="manager clear" id="im_mads">\
<label>Information Manager:</label>\
<select id="im_mad" name="im">\
<option value="im_kvm">KVM</option>\
<option value="im_xen">XEN</option>\
<option value="im_ec2">EC2</option>\
<option value="im_dummy">Dummy</option>\
</select>\
<option value="im_kvm">KVM</option>\
<option value="im_xen">XEN</option>\
<option value="im_ec2">EC2</option>\
<option value="im_dummy">Dummy</option>\
</select>\
</div>\
<div class="manager clear" id="tm_mads">\
<label>Transfer Manager:</label>\
<select id="tm_mad" name="tm">\
<option value="tm_nfs">NFS</option>\
<option value="tm_ssh">SSH</option>\
<option value="tm_dummy">Dummy</option>\
</select>\
<option value="tm_nfs">NFS</option>\
<option value="tm_ssh">SSH</option>\
<option value="tm_dummy">Dummy</option>\
</select>\
</div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<div><button class="button" id="create_host_submit" value="OpenNebula.Host.create">Create</button>\
<button class="button" type="reset" value="reset">Reset</button></div>\
</div>\
<div><button class="button" id="create_host_submit" value="OpenNebula.Host.create">Create</button>\
<button class="button" type="reset" value="reset">Reset</button></div>\
</div>\
</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,133 +207,44 @@ 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",
content:""
},
"host_template_tab" : {
title: "Host template",
content: ""
@ -375,27 +257,26 @@ var host_info_panel = {
var hosts_tab = {
title: 'Hosts &amp; Clusters',
title: 'Hosts',
content: hosts_tab_content,
buttons: host_buttons,
condition: True
}
}
Sunstone.addActions(host_actions);
Sunstone.addMainTab('hosts_tab',hosts_tab);
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);
@ -431,169 +312,149 @@ function hostElementArray(host_json){
</div>';
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) ];
return [
'<input type="checkbox" id="host_'+host.ID+'" name="selected_items" value="'+host.ID+'"/>',
host.ID,
host.NAME,
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(){
//Grab table data from the host_list
host_list_array.push(hostElementArray(this));
});
$.each(host_list,function(){
//Grab table data from the host_list
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">\
<thead>\
<tr><th colspan="2">Host information - '+host_info.NAME+'</th></tr>\
</thead>\
<tr>\
<td class="key_td">ID</td>\
<td class="value_td">'+host_info.ID+'</td>\
</tr>\
<tr>\
<td class="key_td">State</td>\
<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>\
</tr>\
<tr>\
<td class="key_td">IM MAD</td>\
<td class="value_td">'+host_info.IM_MAD+'</td>\
</tr>\
<tr>\
<td class="key_td">VM MAD</td>\
<td class="value_td">'+host_info.VM_MAD+'</td>\
</tr>\
<tr>\
<td class="key_td">TM MAD</td>\
<td class="value_td">'+host_info.TM_MAD+'</td>\
</tr>\
</table>\
<table id="host_shares_table" class="info_table">\
<thead>\
<tr><th colspan="2">Host shares</th></tr>\
</thead>\
<tr>\
<td class="key_td">Max Mem</td>\
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.MAX_MEM)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used Mem (real)</td>\
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.USED_MEM)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used Mem (allocated)</td>\
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.MAX_USAGE)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used CPU (real)</td>\
<td class="value_td">'+host_info.HOST_SHARE.USED_CPU+'</td>\
</tr>\
<tr>\
<td class="key_td">Used CPU (allocated)</td>\
<td class="value_td">'+host_info.HOST_SHARE.CPU_USAGE+'</td>\
</tr>\
<tr>\
<td class="key_td">Running VMs</td>\
<td class="value_td">'+host_info.HOST_SHARE.RUNNING_VMS+'</td>\
</tr>\
</table>'
'<table id="info_host_table" class="info_table">\
<thead>\
<tr><th colspan="2">Host information - '+host_info.NAME+'</th></tr>\
</thead>\
<tbody>\
<tr>\
<td class="key_td">ID</td>\
<td class="value_td">'+host_info.ID+'</td>\
</tr>\
<tr>\
<td class="key_td">State</td>\
<td class="value_td">'+OpenNebula.Helper.resource_state("host",host_info.STATE)+'</td>\
</tr>\
<tr>\
<td class="key_td">IM MAD</td>\
<td class="value_td">'+host_info.IM_MAD+'</td>\
</tr>\
<tr>\
<td class="key_td">VM MAD</td>\
<td class="value_td">'+host_info.VM_MAD+'</td>\
</tr>\
<tr>\
<td class="key_td">TM MAD</td>\
<td class="value_td">'+host_info.TM_MAD+'</td>\
</tr>\
</tbody>\
</table>\
<table id="host_shares_table" class="info_table">\
<thead>\
<tr><th colspan="2">Host shares</th></tr>\
</thead>\
<tbody>\
<tr>\
<td class="key_td">Max Mem</td>\
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.MAX_MEM)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used Mem (real)</td>\
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.USED_MEM)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used Mem (allocated)</td>\
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.MAX_USAGE)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used CPU (real)</td>\
<td class="value_td">'+host_info.HOST_SHARE.USED_CPU+'</td>\
</tr>\
<tr>\
<td class="key_td">Used CPU (allocated)</td>\
<td class="value_td">'+host_info.HOST_SHARE.CPU_USAGE+'</td>\
</tr>\
<tr>\
<td class="key_td">Running VMs</td>\
<td class="value_td">'+host_info.HOST_SHARE.RUNNING_VMS+'</td>\
</tr>\
</tbody>\
</table>'
}
//Template tab
var template_tab = {
title : "Host template",
content :
'<table id="host_template_table" class="info_table">\
<thead><tr><th colspan="2">Host template</th></tr></thead>'+
prettyPrintJSON(host_info.TEMPLATE)+
'</table>'
content :
'<table id="host_template_table" class="info_table">\
<thead><tr><th colspan="2">Host template</th></tr></thead>'+
prettyPrintJSON(host_info.TEMPLATE)+
'</table>'
}
var monitor_tab = {
@ -620,122 +481,84 @@ function setupCreateHostDialog(){
$('div#dialogs').append('<div title="Create host" id="create_host_dialog"></div>');
$('div#create_host_dialog').html(create_host_tmpl);
$('#create_host_dialog').dialog({
autoOpen: false,
modal: true,
width: 500
});
autoOpen: false,
modal: true,
width: 500
});
$('#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;
});
$('#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
//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,
"bSortClasses": false,
"bAutoWidth":false,
"sPaginationType": "full_numbers",
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0,4] },
{ "sWidth": "35px", "aTargets": [1] },
{ "sWidth": "200px", "aTargets": [5,6] }
]
"bJQueryUI": true,
"bSortClasses": false,
"bAutoWidth":false,
"sPaginationType": "full_numbers",
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0,3] },
{ "sWidth": "35px", "aTargets": [1] },
{ "sWidth": "200px", "aTargets": [4,5] }
]
});
//preload it
dataTable_hosts.fnClearTable();
addElement([
spinner,
'','','','','','',''],dataTable_hosts);
'','','','','',''],dataTable_hosts);
Sunstone.runAction("Host.list");
Sunstone.runAction("Cluster.list");
setupCreateHostDialog();
setupCreateClusterDialog();
setHostAutorefresh();
setClusterAutorefresh();
initCheckAllBoxes(dataTable_hosts);
tableCheckboxesListener(dataTable_hosts);
hostInfoListener();
});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -15,8 +15,11 @@
/* -------------------------------------------------------------------------- */
/*Users tab plugin*/
var user_list_json = {};
var dataTable_users;
var users_select="";
var users_tab_content =
var users_tab_content =
'<form id="user_form" action="" action="javascript:alert(\'js error!\');">\
<div class="action_blocks">\
</div>\
@ -26,6 +29,7 @@ var users_tab_content =
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
<th>ID</th>\
<th>Name</th>\
<th>Groups</th>\
</tr>\
</thead>\
<tbody id="tbodyusers">\
@ -36,24 +40,21 @@ var users_tab_content =
var create_user_tmpl =
'<form id="create_user_form" action="">\
<fieldset>\
<div>\
<label for="username">Username:</label>\
<input type="text" name="username" id="username" /><br />\
<label for="pass">Password:</label>\
<input type="password" name="pass" id="pass" />\
</div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_user_submit" value="user/create">Create</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
<div>\
<label for="username">Username:</label>\
<input type="text" name="username" id="username" /><br />\
<label for="pass">Password:</label>\
<input type="password" name="pass" id="pass" />\
</div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_user_submit" value="user/create">Create</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>';
var user_list_json = {};
var dataTable_users;
var user_actions = {
"User.create" : {
type: "create",
@ -62,19 +63,19 @@ var user_actions = {
error: onError,
notify: true
},
"User.create_dialog" : {
type: "custom",
call: popUpCreateUserDialog
},
"User.list" : {
type: "list",
call: OpenNebula.User.list,
callback: updateUsersView,
error: onError
},
"User.refresh" : {
type: "custom",
call: function () {
@ -82,16 +83,20 @@ var user_actions = {
Sunstone.runAction("User.list");
},
},
"User.autorefresh" : {
type: "custom",
call: function(){
OpenNebula.User.list({timeout: true, success: updateUsersView, error: onError});
OpenNebula.User.list({
timeout: true,
success: updateUsersView,
error: onError
});
},
condition: function(){ uid == 0 },
notify: false
},
"User.delete" : {
type: "multiple",
call: OpenNebula.User.delete,
@ -134,81 +139,116 @@ Sunstone.addMainTab('users_tab',users_tab);
// Returns an array with the values from the user_json ready to be
// added to the dataTable
function userElementArray(user_json){
var user = user_json.USER;
var user = user_json.USER;
if (!user.NAME || user.NAME == {}){
name = "";
} else {
name = user.NAME;
}
return [
'<input type="checkbox" id="user_'+user.ID+'" name="selected_items" value="'+user.ID+'"/>',
user.ID,
name
]
var i = 1;
var groups_str=getGroupName(user.GID)+", ";
var groups_full_str=getGroupName(user.GID)+", ";
var group_field;
if (user.GROUPS.ID){
$.each(user.GROUPS.ID,function() {
if (i<=5) {
groups_str+=getGroupName(this)+", ";
};
groups_full_str+=getGroupName(this)+", ";
i++;
});
if (i>0){
groups_str = groups_str.slice(0, -2);
groups_full_str = groups_str.slice(0, -2);
};
if (i>5){
groups_str+="...";
group_field = '<div class="shortened_info">'+groups_str+'</div><div class="full_info" style="display:none">'+groups_full_str+'</div>';
} else {
group_field=groups_str;
};
}
return [
'<input type="checkbox" id="user_'+user.ID+'" name="selected_items" value="'+user.ID+'"/>',
user.ID,
name,
group_field
]
}
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);
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
function setupCreateUserDialog(){
$('div#dialogs').append('<div title="Create user" id="create_user_dialog"></div>');
$('#create_user_dialog').html(create_user_tmpl);
$('div#dialogs').append('<div title="Create user" id="create_user_dialog"></div>');
$('#create_user_dialog').html(create_user_tmpl);
//Prepare jquery dialog
$('#create_user_dialog').dialog({
autoOpen: false,
modal:true,
width: 400
});
//Prepare jquery dialog
$('#create_user_dialog').dialog({
autoOpen: false,
modal:true,
width: 400
});
$('#create_user_dialog button').button();
$('#create_user_form').submit(function(){
var user_name=$('#username',this).val();
var user_password=$('#pass',this).val();
var user_name=$('#username',this).val();
var user_password=$('#pass',this).val();
if (!user_name.length && !user_password.length){
notifyError("User name and password must be filled in");
return false;
}
var user_json = { "user" :
{ "name" : user_name,
"password" : user_password }
};
Sunstone.runAction("User.create",user_json);
$('#create_user_dialog').dialog('close');
return false;
});
var user_json = { "user" :
{ "name" : user_name,
"password" : user_password }
};
Sunstone.runAction("User.create",user_json);
$('#create_user_dialog').dialog('close');
return false;
});
}
function popUpCreateUserDialog(){
@ -218,16 +258,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,22 +275,23 @@ $(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);
'','',''],dataTable_users);
Sunstone.runAction("User.list");
setupCreateUserDialog();
setUserAutorefresh();
initCheckAllBoxes(dataTable_users);
tableCheckboxesListener(dataTable_users);
shortenedInfoFields('#datatable_users');
}
})

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@
/*Virtual networks tab plugin*/
var vnets_tab_content =
var vnets_tab_content =
'<form id="virtualNetworks_form" action="javascript:alert(\'js error!\');">\
<div class="action_blocks">\
</div>\
@ -25,7 +25,8 @@ var vnets_tab_content =
<tr>\
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
<th>ID</th>\
<th>User</th>\
<th>Owner</th>\
<th>Group</th>\
<th>Name</th>\
<th>Type</th>\
<th>Bridge</th>\
@ -40,84 +41,84 @@ var vnets_tab_content =
var create_vn_tmpl =
'<div id="vn_tabs">\
<ul>\
<li><a href="#easy">Wizard</a></li>\
<li><a href="#manual">Advanced mode</a></li>\
</ul>\
<div id="easy">\
<form id="create_vn_form_easy" action="">\
<fieldset>\
<label for="name">Name:</label>\
<input type="text" name="name" id="name" /><br />\
</fieldset>\
<fieldset>\
<label for="bridge">Bridge:</label>\
<input type="text" name="bridge" id="bridge" /><br />\
</fieldset>\
<fieldset>\
<label style="height:2em;">Network type:</label>\
<input type="radio" name="fixed_ranged" id="fixed_check" value="fixed" checked="checked">Fixed network</input><br />\
<input type="radio" name="fixed_ranged" id="ranged_check" value="ranged">Ranged network</input><br />\
</fieldset>\
<div class="clear"></div>\
<div id="easy_tabs">\
<div id="fixed">\
<fieldset>\
<label for="leaseip">Lease IP:</label>\
<input type="text" name="leaseip" id="leaseip" /><br />\
<label for="leasemac">Lease MAC (opt):</label>\
<input type="text" name="leasemac" id="leasemac" />\
<div class="clear"></div>\
<button class="add_remove_button add_button" id="add_lease" value="add/lease">\
Add\
</button>\
<button class="add_remove_button" id="remove_lease" value="remove/lease">\
Remove selected\
</button>\
<label for="leases">Current leases:</label>\
<select id="leases" name="leases" size="10" style="width:150px" multiple>\
<!-- insert leases -->\
</select><br />\
</fieldset>\
</div>\
<div id="ranged">\
<fieldset>\
<label for="net_address">Network Address:</label>\
<input type="text" name="net_address" id="net_address" /><br />\
<label for="net_size">Network size:</label>\
<input type="text" name="net_size" id="net_size" />\
</fieldset>\
</div>\
</div>\
<div class="clear"></div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_vn_submit_easy" value="vn/create">\
Create\
</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>\
</div>\
<div id="manual">\
<form id="create_vn_form_manual" action="">\
<h3 style="margin-bottom:10px;">Write the Virtual Network template here</h3>\
<fieldset style="border-top:none;">\
<textarea id="template" rows="15" style="width:100%;"></textarea>\
<div class="clear"></div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_vn_submit_manual" value="vn/create">\
Create\
</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>\
</div>\
<ul>\
<li><a href="#easy">Wizard</a></li>\
<li><a href="#manual">Advanced mode</a></li>\
</ul>\
<div id="easy">\
<form id="create_vn_form_easy" action="">\
<fieldset>\
<label for="name">Name:</label>\
<input type="text" name="name" id="name" /><br />\
</fieldset>\
<fieldset>\
<label for="bridge">Bridge:</label>\
<input type="text" name="bridge" id="bridge" /><br />\
</fieldset>\
<fieldset>\
<label style="height:2em;">Network type:</label>\
<input type="radio" name="fixed_ranged" id="fixed_check" value="fixed" checked="checked">Fixed network</input><br />\
<input type="radio" name="fixed_ranged" id="ranged_check" value="ranged">Ranged network</input><br />\
</fieldset>\
<div class="clear"></div>\
<div id="easy_tabs">\
<div id="fixed">\
<fieldset>\
<label for="leaseip">Lease IP:</label>\
<input type="text" name="leaseip" id="leaseip" /><br />\
<label for="leasemac">Lease MAC (opt):</label>\
<input type="text" name="leasemac" id="leasemac" />\
<div class="clear"></div>\
<button class="add_remove_button add_button" id="add_lease" value="add/lease">\
Add\
</button>\
<button class="add_remove_button" id="remove_lease" value="remove/lease">\
Remove selected\
</button>\
<label for="leases">Current leases:</label>\
<select id="leases" name="leases" size="10" style="width:150px" multiple>\
<!-- insert leases -->\
</select><br />\
</fieldset>\
</div>\
<div id="ranged">\
<fieldset>\
<label for="net_address">Network Address:</label>\
<input type="text" name="net_address" id="net_address" /><br />\
<label for="net_size">Network size:</label>\
<input type="text" name="net_size" id="net_size" />\
</fieldset>\
</div>\
</div>\
<div class="clear"></div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_vn_submit_easy" value="vn/create">\
Create\
</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>\
</div>\
<div id="manual">\
<form id="create_vn_form_manual" action="">\
<h3 style="margin-bottom:10px;">Write the Virtual Network template here</h3>\
<fieldset style="border-top:none;">\
<textarea id="template" rows="15" style="width:100%;"></textarea>\
<div class="clear"></div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_vn_submit_manual" value="vn/create">\
Create\
</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>\
</div>\
</div>';
var vnetworks_select="";
@ -134,34 +135,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 +170,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 +188,7 @@ var vnet_actions = {
error: onError,
notify: true
},
"Network.unpublish" : {
type: "multiple",
call: OpenNebula.Network.unpublish,
@ -198,7 +199,7 @@ var vnet_actions = {
error: onError,
notify: true
},
"Network.delete" : {
type: "multiple",
call: OpenNebula.Network.delete,
@ -206,8 +207,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.chgrp,
callback: function (req) {
Sunstone.runAction("Network.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_vNetworks); },
error:onError,
notify: true
}
}
@ -218,25 +240,41 @@ var vnet_buttons = {
img: "/images/Refresh-icon.png",
condition: True
},
"Network.create_dialog" : {
type: "create_dialog",
text: "+ New",
condition: True
},
"Network.publish" : {
type: "action",
text: "Publish",
condition: True
},
"Network.unpublish" : {
type: "action",
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",
text: "Delete",
@ -268,275 +306,270 @@ Sunstone.addInfoPanel('vnet_info_panel',vnet_info_panel);
//returns an array with the VNET information fetched from the JSON object
function vNetworkElementArray(vn_json){
var network = vn_json.VNET;
var network = vn_json.VNET;
var total_leases = "0";
if (network.TOTAL_LEASES){
total_leases = network.TOTAL_LEASES;
} else if (network.LEASES && network.LEASES.LEASE){
total_leases = network.LEASES.LEASE.length ? network.LEASES.LEASE.length : "1";
}
//Does the JSON bring a username field? Otherwise try
//to get it from the users dataTable
var username = network.USERNAME? network.USERNAME : getUserName(network.UID)
return ['<input type="checkbox" id="vnetwork_'+network.ID+'" name="selected_items" value="'+network.ID+'"/>',
network.ID,
username,
network.NAME,
parseInt(network.TYPE) ? "FIXED" : "RANGED",
network.BRIDGE,
parseInt(network.PUBLIC) ? "yes" : "no",
total_leases ];
return [
'<input type="checkbox" id="vnetwork_'+network.ID+'" name="selected_items" value="'+network.ID+'"/>',
network.ID,
getUserName(network.UID),
getGroupName(network.GID),
network.NAME,
parseInt(network.TYPE) ? "FIXED" : "RANGED",
network.BRIDGE,
parseInt(network.PUBLIC) ? "yes" : "no",
total_leases ];
}
//Adds a listener to show the extended info when clicking on a row
function vNetworkInfoListener(){
$('#tbodyvnetworks tr').live("click", function(e){
if ($(e.target).is('input')) {return true;}
$('#tbodyvnetworks tr').live("click", function(e){
if ($(e.target).is('input')) {return true;}
popDialogLoading();
var aData = dataTable_vNetworks.fnGetData(this);
var id = $(aData[0]).val();
Sunstone.runAction("Network.showinfo",id);
return false;
});
var aData = dataTable_vNetworks.fnGetData(this);
var id = $(aData[0]).val();
Sunstone.runAction("Network.showinfo",id);
return false;
});
}
//updates the vnet select different options
function updateNetworkSelect(){
vnetworks_select=
makeSelectOptions(dataTable_vNetworks,1,3,6,"no",2);
vnetworks_select=
makeSelectOptions(dataTable_vNetworks,1,4,7,"no",2);
//update static selectors:
//update static selectors:
//in the VM creation dialog
$('div.vm_section#networks select#NETWORK_ID').html(vnetworks_select);
$('div.vm_section#networks select#NETWORK_ID').html(vnetworks_select);
}
//Callback to update a vnet element after an action on it
function updateVNetworkElement(request, vn_json){
id = vn_json.VNET.ID;
element = vNetworkElementArray(vn_json);
updateSingleElement(element,dataTable_vNetworks,'#vnetwork_'+id);
id = vn_json.VNET.ID;
element = vNetworkElementArray(vn_json);
updateSingleElement(element,dataTable_vNetworks,'#vnetwork_'+id);
updateNetworkSelect();
}
//Callback to delete a vnet element from the table
function deleteVNetworkElement(req){
deleteElement(dataTable_vNetworks,'#vnetwork_'+req.request.data);
deleteElement(dataTable_vNetworks,'#vnetwork_'+req.request.data);
updateNetworkSelect();
}
//Callback to add a new element
function addVNetworkElement(request,vn_json){
var element = vNetworkElementArray(vn_json);
addElement(element,dataTable_vNetworks);
var element = vNetworkElementArray(vn_json);
addElement(element,dataTable_vNetworks);
updateNetworkSelect();
}
//updates the list of virtual networks
function updateVNetworksView(request, network_list){
network_list_json = network_list;
var network_list_array = [];
network_list_json = network_list;
var network_list_array = [];
$.each(network_list,function(){
network_list_array.push(vNetworkElementArray(this));
});
$.each(network_list,function(){
network_list_array.push(vNetworkElementArray(this));
});
updateView(network_list_array,dataTable_vNetworks);
updateNetworkSelect();
updateView(network_list_array,dataTable_vNetworks);
updateNetworkSelect();
//dependency with dashboard
updateDashboard("vnets",network_list_json);
updateDashboard("vnets",network_list_json);
}
//updates the information panel tabs and pops the panel up
function updateVNetworkInfo(request,vn){
var vn_info = vn.VNET;
var info_tab_content =
'<table id="info_vn_table" class="info_table">\
<thead>\
<tr><th colspan="2">Virtual Network '+vn_info.ID+' information</th></tr>\
</thead>\
<tr>\
<td class="key_td">ID</td>\
<td class="value_td">'+vn_info.ID+'</td>\
</tr>\
<tr>\
<td class="key_td">UID</td>\
<td class="value_td">'+vn_info.UID+'</td>\
</tr>\
<tr>\
<td class="key_td">Public</td>\
<td class="value_td">'+(parseInt(vn_info.PUBLIC) ? "yes" : "no" )+'</td>\
</tr>\
</table>';
//if it is a fixed VNET we can add leases information
var vn_info = vn.VNET;
var info_tab_content =
'<table id="info_vn_table" class="info_table">\
<thead>\
<tr><th colspan="2">Virtual Network '+vn_info.ID+' information</th></tr>\
</thead>\
<tr>\
<td class="key_td">ID</td>\
<td class="value_td">'+vn_info.ID+'</td>\
<tr>\
<tr>\
<td class="key_td">UID</td>\
<td class="value_td">'+vn_info.UID+'</td>\
</tr>\
<tr>\
<td class="key_td">Public</td>\
<td class="value_td">'+(parseInt(vn_info.PUBLIC) ? "yes" : "no" )+'</td>\
</tr>\
</table>';
//if it is a fixed VNET we can add leases information
if (vn_info.TEMPLATE.TYPE == "FIXED"){
info_tab_content += '<table id="vn_leases_info_table" class="info_table">\
<thead>\
<tr><th colspan="2">Leases information</th></tr>\
</thead>'+
prettyPrintJSON(vn_info.LEASES.LEASE)+
'</table>';
info_tab_content +=
'<table id="vn_leases_info_table" class="info_table">\
<thead>\
<tr><th colspan="2">Leases information</th></tr>\
</thead>'+
prettyPrintJSON(vn_info.TEMPLATE.LEASES)+
'</table>';
}
var info_tab = {
var info_tab = {
title: "Virtual Network information",
content: info_tab_content
}
var template_tab = {
title: "Virtual Network template",
content: '<table id="vn_template_table" class="info_table">\
<thead><tr><th colspan="2">Virtual Network template</th></tr></thead>'+
prettyPrintJSON(vn_info.TEMPLATE)+
'</table>'
content:
'<table id="vn_template_table" class="info_table">\
<thead><tr><th colspan="2">Virtual Network template</th></tr></thead>'+
prettyPrintJSON(vn_info.TEMPLATE)+
'</table>'
}
Sunstone.updateInfoPanelTab("vnet_info_panel","vnet_info_tab",info_tab);
Sunstone.updateInfoPanelTab("vnet_info_panel","vnet_template_tab",template_tab);
Sunstone.popUpInfoPanel("vnet_info_panel");
}
//Prepares the vnet creation dialog
function setupCreateVNetDialog() {
$('div#dialogs').append('<div title="Create Virtual Network" id="create_vn_dialog"></div>');
$('#create_vn_dialog').html(create_vn_tmpl);
//Prepare the jquery-ui dialog. Set style options here.
$('#create_vn_dialog').dialog({
autoOpen: false,
modal: true,
width: 475,
height: 500
});
$('#create_vn_dialog').html(create_vn_tmpl);
//Make the tabs look nice for the creation mode
$('#vn_tabs').tabs();
//Prepare the jquery-ui dialog. Set style options here.
$('#create_vn_dialog').dialog({
autoOpen: false,
modal: true,
width: 475,
height: 500
});
//Make the tabs look nice for the creation mode
$('#vn_tabs').tabs();
$('div#ranged').hide();
$('#fixed_check').click(function(){
$('div#fixed').show();
$('div#ranged').hide();
$('div#fixed').show();
$('div#ranged').hide();
});
$('#ranged_check').click(function(){
$('div#fixed').hide();
$('div#ranged').show();
});
$('#create_vn_dialog button').button();
//When we hit the add lease button...
$('#add_lease').click(function(){
var create_form = $('#create_vn_form_easy'); //this is our scope
//Fetch the interesting values
var lease_ip = $('#leaseip',create_form).val();
var lease_mac = $('#leasemac',create_form).val();
//We don't add anything to the list if there is nothing to add
if (lease_ip == null) {
notifyError("Please provide a lease IP");
return false;
};
$('#create_vn_dialog button').button();
var lease = ""; //contains the HTML to be included in the select box
if (lease_mac == "") {
lease='<option value="' + lease_ip + '">' + lease_ip + '</option>';
} else {
lease='<option value="' +
lease_ip + ',' +
lease_mac + '">' +
lease_ip + ',' + lease_mac +
'</option>';
};
//When we hit the add lease button...
$('#add_lease').click(function(){
var create_form = $('#create_vn_form_easy'); //this is our scope
//We append the HTML into the select box.
$('select#leases').append(lease);
return false;
});
//Fetch the interesting values
var lease_ip = $('#leaseip',create_form).val();
var lease_mac = $('#leasemac',create_form).val();
$('#remove_lease').click(function(){
$('select#leases :selected').remove();
return false;
});
//We don't add anything to the list if there is nothing to add
if (lease_ip == null) {
notifyError("Please provide a lease IP");
return false;
};
//Handle submission of the easy mode
$('#create_vn_form_easy').submit(function(){
//Fetch values
var name = $('#name',this).val();
var lease = ""; //contains the HTML to be included in the select box
if (lease_mac == "") {
lease='<option value="' + lease_ip + '">' + lease_ip + '</option>';
} else {
lease='<option value="' +
lease_ip + ',' +
lease_mac + '">' +
lease_ip + ',' + lease_mac +
'</option>';
};
//We append the HTML into the select box.
$('select#leases').append(lease);
return false;
});
$('#remove_lease').click(function(){
$('select#leases :selected').remove();
return false;
});
//Handle submission of the easy mode
$('#create_vn_form_easy').submit(function(){
//Fetch values
var name = $('#name',this).val();
if (!name.length){
notifyError("Virtual Network name missing!");
return false;
}
var bridge = $('#bridge',this).val();
var type = $('input:checked',this).val();
var bridge = $('#bridge',this).val();
var type = $('input:checked',this).val();
//TODO: Name and bridge provided?!
//TODO: Name and bridge provided?!
var network_json = null;
if (type == "fixed") {
var leases = $('#leases option', this);
var leases_obj=[];
var network_json = null;
if (type == "fixed") {
var leases = $('#leases option', this);
var leases_obj=[];
//for each specified lease we prepare the JSON object
$.each(leases,function(){
leases_obj.push({"ip": $(this).val() });
});
//for each specified lease we prepare the JSON object
$.each(leases,function(){
leases_obj.push({"ip": $(this).val() });
});
//and construct the final data for the request
network_json = {
"vnet" : {
"type" : "FIXED",
"leases" : leases_obj,
"bridge" : bridge,
"name" : name }};
}
else { //type ranged
//and construct the final data for the request
network_json = {
"vnet" : {
"type" : "FIXED",
"leases" : leases_obj,
"bridge" : bridge,
"name" : name }};
}
else { //type ranged
var network_addr = $('#net_address',this).val();
var network_size = $('#net_size',this).val();
if (!network_addr.length){
notifyError("Please provide a network address");
return false;
};
var network_addr = $('#net_address',this).val();
var network_size = $('#net_size',this).val();
if (!network_addr.length){
notifyError("Please provide a network address");
return false;
};
//we form the object for the request
network_json = {
"vnet" : {
"type" : "RANGED",
"bridge" : bridge,
"network_size" : network_size,
"network_address" : network_addr,
"name" : name }
};
};
//we form the object for the request
network_json = {
"vnet" : {
"type" : "RANGED",
"bridge" : bridge,
"network_size" : network_size,
"network_address" : network_addr,
"name" : name }
};
};
//Create the VNetwork.
//Create the VNetwork.
Sunstone.runAction("Network.create",network_json);
$('#create_vn_dialog').dialog('close');
return false;
});
$('#create_vn_dialog').dialog('close');
return false;
});
$('#create_vn_form_manual').submit(function(){
var template=$('#template',this).val();
$('#create_vn_form_manual').submit(function(){
var template=$('#template',this).val();
var vnet_json = {vnet: {vnet_raw: template}};
Sunstone.runAction("Network.create",vnet_json);
$('#create_vn_dialog').dialog('close');
return false;
});
return false;
});
}
function popUpCreateVnetDialog() {
@ -545,44 +578,41 @@ function popUpCreateVnetDialog() {
function setVNetAutorefresh() {
setInterval(function(){
var checked = $('input:checked',dataTable_vNetworks.fnGetNodes());
var checked = $('input:checked',dataTable_vNetworks.fnGetNodes());
var filter = $("#datatable_vnetworks_filter input").attr("value");
if (!checked.length && !filter.length){
Sunstone.runAction("Network.autorefresh");
}
},INTERVAL+someTime());
if (!checked.length && !filter.length){
Sunstone.runAction("Network.autorefresh");
}
},INTERVAL+someTime());
}
//The DOM is ready and the ready() from sunstone.js
//has been executed at this point.
//The DOM is ready and the ready() from sunstone.js
//has been executed at this point.
$(document).ready(function(){
dataTable_vNetworks = $("#datatable_vnetworks").dataTable({
"bJQueryUI": true,
"bSortClasses": false,
"bAutoWidth":false,
"sPaginationType": "full_numbers",
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0,4,5,6,7] },
{ "sWidth": "35px", "aTargets": [1] },
{ "sWidth": "100px", "aTargets": [2] }
]
dataTable_vNetworks = $("#datatable_vnetworks").dataTable({
"bJQueryUI": true,
"bSortClasses": false,
"bAutoWidth":false,
"sPaginationType": "full_numbers",
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0,5,6,7,8] },
{ "sWidth": "35px", "aTargets": [1] },
{ "sWidth": "100px", "aTargets": [2,3] }
]
});
dataTable_vNetworks.fnClearTable();
addElement([
spinner,
'','','','','','',''],dataTable_vNetworks);
'','','','','','','',''],dataTable_vNetworks);
Sunstone.runAction("Network.list");
setupCreateVNetDialog();
setVNetAutorefresh();
initCheckAllBoxes(dataTable_vNetworks);
tableCheckboxesListener(dataTable_vNetworks);
vNetworkInfoListener();
});

View File

@ -69,13 +69,13 @@ function humanize_size(value) {
//Wrapper to add an element to a dataTable
function addElement(element,data_table){
data_table.fnAddData(element);
data_table.fnAddData(element);
}
//deletes an element with id 'tag' from a dataTable
function deleteElement(data_table,tag){
var tr = $(tag).parents('tr')[0];
data_table.fnDeleteRow(tr);
var tr = $(tag).parents('tr')[0];
data_table.fnDeleteRow(tr);
$('input',data_table).trigger("change");
}
@ -101,11 +101,11 @@ function tableCheckboxesListener(dataTable){
var context = table.parents('form');
var nodes = $('tr',table);
var total_length = nodes.length;
var checked_length = $('input:checked',nodes).length;
var checked_length = $('input:checked',nodes).length;
var last_action_b = $('.last_action_button',context);
//if all elements are checked we check the check-all box
if (total_length == checked_length && total_length != 0){
$('.check_all',dataTable).attr("checked","checked");
@ -125,7 +125,7 @@ function tableCheckboxesListener(dataTable){
$('.top_button, .list_button',context).button("disable");
last_action_b.button("disable");
}
//any case the create dialog buttons should always be enabled.
$('.create_dialog_button',context).button("enable");
$('.alwaysActive',context).button("enable");
@ -136,19 +136,19 @@ function tableCheckboxesListener(dataTable){
// Updates a data_table, with a 2D array containing the new values
// Does a partial redraw, so the filter and pagination are kept
function updateView(item_list,data_table){
if (data_table!=null) {
data_table.fnClearTable();
data_table.fnAddData(item_list);
data_table.fnDraw(false);
};
if (data_table!=null) {
data_table.fnClearTable();
data_table.fnAddData(item_list);
data_table.fnDraw(false);
};
}
//replaces an element with id 'tag' in a dataTable with a new one
function updateSingleElement(element,data_table,tag){
var nodes = data_table.fnGetNodes();
var tr = $(tag,nodes).parents('tr')[0];
var position = data_table.fnGetPosition(tr);
data_table.fnUpdate(element,position,0,false);
var tr = $(tag,nodes).parents('tr')[0];
var position = data_table.fnGetPosition(tr);
data_table.fnUpdate(element,position,0,false);
$('input',data_table).trigger("change");
}
@ -156,11 +156,11 @@ function updateSingleElement(element,data_table,tag){
// Returns an string in the form key=value key=value ...
// Does not explore objects in depth.
function stringJSON(json){
var str = ""
for (field in json) {
str+= field + '=' + json[field] + ' ';
}
return str;
var str = ""
for (field in json) {
str+= field + '=' + json[field] + ' ';
}
return str;
}
//Notifications
@ -223,48 +223,48 @@ function prettyPrintRowJSON(field,value,padding,weight, border_bottom,padding_to
if (typeof value == 'object'){
//name of field row
str += '<tr>\
<td class="key_td" style=\
"padding-left:'+padding+'px;\
font-weight:'+weight+';\
border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px;">'
+field+
'</td>\
<td class="value_td" style=\
"border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px">\
</td>\
</tr>';
<td class="key_td" style=\
"padding-left:'+padding+'px;\
font-weight:'+weight+';\
border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px;">'
+field+
'</td>\
<td class="value_td" style=\
"border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px">\
</td>\
</tr>';
//attributes rows
//empty row - prettyprint - empty row
str += '<tr>\
<td class="key_td" style="border-bottom:0"></td>\
<td class="value_td" style="border-bottom:0"></td>\
</tr>' +
prettyPrintJSON(value,padding+25,"normal","0",1) +
'<tr>\
<td class="key_td"></td>\
<td class="value_td"></td>\
</tr>';
} else {
<td class="key_td" style="border-bottom:0"></td>\
<td class="value_td" style="border-bottom:0"></td>\
</tr>' +
prettyPrintJSON(value,padding+25,"normal","0",1) +
'<tr>\
<td class="key_td"></td>\
<td class="value_td"></td>\
</tr>';
} else {
str += '<tr>\
<td class="key_td" style="\
padding-left:'+padding+'px;\
font-weight:'+weight+';\
border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px">'+
field+
'</td>\
<td class="value_td" style="\
border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px">'+
value+
'</td>\
</tr>';
<td class="key_td" style="\
padding-left:'+padding+'px;\
font-weight:'+weight+';\
border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px">'+
field+
'</td>\
<td class="value_td" style="\
border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px">'+
value+
'</td>\
</tr>';
};
return str;
@ -273,27 +273,27 @@ function prettyPrintRowJSON(field,value,padding,weight, border_bottom,padding_to
//Add a listener to the check-all box of a datatable, enabling it to
//check and uncheck all the checkboxes of its elements.
function initCheckAllBoxes(datatable){
//not showing nice in that position
//$('.check_all').button({ icons: {primary : "ui-icon-check" },
// text : true});
//small css hack
$('.check_all',datatable).css({"border":"2px"});
$('.check_all',datatable).click(function(){
if ($(this).attr("checked")) {
$('tbody input:checkbox',
$(this).parents("table")).each(function(){
$(this).attr("checked","checked");
});
//not showing nice in that position
//$('.check_all').button({ icons: {primary : "ui-icon-check" },
// text : true});
} else {
$('tbody input:checkbox',
$(this).parents("table")).each(function(){
$(this).removeAttr("checked");
});
//small css hack
$('.check_all',datatable).css({"border":"2px"});
$('.check_all',datatable).click(function(){
if ($(this).attr("checked")) {
$('tbody input:checkbox',
$(this).parents("table")).each(function(){
$(this).attr("checked","checked");
});
} else {
$('tbody input:checkbox',
$(this).parents("table")).each(function(){
$(this).removeAttr("checked");
});
}
$('tbody input:checkbox',$(this).parents("table")).trigger("change");
});
});
}
//standard handling for the server errors on ajax requests.
@ -309,9 +309,9 @@ function onError(request,error_json) {
//redirect to login if unauthenticated
if (error_json.error.http_status=="401") {
window.location.href = "/login";
window.location.href = "/login";
};
if (!message){
notifyError("Cannot contact server: is Sunstone server running and reachable?");
return false;
@ -370,79 +370,81 @@ function onError(request,error_json) {
function waitingNodes(dataTable){
var nodes = dataTable.fnGetData();
for (var i=0;i<nodes.length;i++){
dataTable.fnUpdate(spinner,i,0);
dataTable.fnUpdate(spinner,i,0);
}
};
//given a user ID, returns an string with the user name.
//To do this it finds the user name in the user dataTable. If it is
//not defined then it returns "uid UID".
//TODO not very nice to hardcode a dataTable here...
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];
return false;
}
});
return user;
return getName(uid,dataTable_users);
}
function getGroupName(gid){
return getName(gid,dataTable_groups);
}
function getName(id,dataTable){
var name = id;
if (typeof(dataTable) == "undefined") {
return name;
}
var nodes = dataTable.fnGetData();
$.each(nodes,function(){
if (id == this[1]) {
name = this[2];
return false;
}
});
return name;
}
//Replaces all class"tip" divs with an information icon that
//displays the tip information on mouseover.
function setupTips(context){
//For each tip in this context
$('div.tip',context).each(function(){
//store the text
var tip = $(this).html();
//replace the text with an icon and spans
$(this).html('<span class="ui-icon ui-icon-info info_icon"></span>');
$(this).append('<span class="tipspan"></span>');
$(this).append('<span class="ui-icon ui-icon-alert man_icon" />');
//For each tip in this context
$('div.tip',context).each(function(){
//store the text
var tip = $(this).html();
//replace the text with an icon and spans
$(this).html('<span class="ui-icon ui-icon-info info_icon"></span>');
$(this).append('<span class="tipspan"></span>');
//add the text to .tipspan
$('span.tipspan',this).html(tip);
//make sure it is not floating in the wrong place
$(this).parent().append('<div class="clear"></div>');
//hide the text
$('span.tipspan',this).hide();
//When the mouse is hovering on the icon we fadein/out
//the tip text
$('span.info_icon',this).hover(function(e){
var top, left;
top = e.pageY - 15;// - $(this).parents('#create_vm_dialog').offset().top - 15;
left = e.pageX + 15;// - $(this).parents('#create_vm_dialog').offset().left;
$(this).next().css(
{"top":top+"px",
"left":left+"px"});
$(this).next().fadeIn();
},function(){
$(this).next().fadeOut();
});
});
$(this).append('<span class="ui-icon ui-icon-alert man_icon" />');
//add the text to .tipspan
$('span.tipspan',this).html(tip);
//make sure it is not floating in the wrong place
$(this).parent().append('<div class="clear"></div>');
//hide the text
$('span.tipspan',this).hide();
//When the mouse is hovering on the icon we fadein/out
//the tip text
$('span.info_icon',this).hover(function(e){
var top, left;
top = e.pageY - 15;// - $(this).parents('#create_vm_dialog').offset().top - 15;
left = e.pageX + 15;// - $(this).parents('#create_vm_dialog').offset().left;
$(this).next().css(
{"top":top+"px",
"left":left+"px"});
$(this).next().fadeIn();
},function(){
$(this).next().fadeOut();
});
});
}
//returns an array of ids of selected elements in a dataTable
function getSelectedNodes(dataTable){
var selected_nodes = [];
if (dataTable != null){
//Which rows of the datatable are checked?
var nodes = $('input:checked',$('tbody',dataTable));
$.each(nodes,function(){
selected_nodes.push($(this).val());
});
//Which rows of the datatable are checked?
var nodes = $('input:checked',$('tbody',dataTable));
$.each(nodes,function(){
selected_nodes.push($(this).val());
});
}
return selected_nodes;
}
@ -450,22 +452,25 @@ function getSelectedNodes(dataTable){
//returns a HTML string with a select input code generated from
//a dataTable
function makeSelectOptions(dataTable,
id_col,name_col,
status_col,
status_bad,
user_col){
id_col,name_col,
status_col,
status_bad,
user_col){
var nodes = dataTable.fnGetData();
var select = "<option value=\"\">Please select</option>";
var array;
$.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>';
}
});
@ -480,7 +485,7 @@ function escapeDoubleQuotes(string){
function generateMonitoringDivs(graphs, id_prefix){
var str = "";
//40% of the width of the screen minus
//40% of the width of the screen minus
//129px (left menu size)
var width = ($(window).width()-129)*45/100;
var id_suffix="";
@ -491,11 +496,13 @@ function generateMonitoringDivs(graphs, id_prefix){
id_suffix=label.replace(/,/g,'_');
id = id_prefix+id_suffix;
str+='<table class="info_table">\
<thead><tr><th colspan="1">'+this.title+'</th></tr></thead>\
<tr><td id="legend_'+id_suffix+'"></td></tr>\
<tr><td style="border:0">\
<div id="'+id+'" style="width:'+width+'px; height:150px;">'+spinner+'</div>\
</td></tr></table>';
<thead><tr><th colspan="1">'+this.title+'</th></tr></thead>\
<tr><td id="legend_'+id_suffix+'"></td></tr>\
<tr><td style="border:0">\
<div id="'+id+'" style="width:'+width+'px; height:150px;">'+
spinner+
'</div>\
</td></tr></table>';
});
return str;
@ -503,7 +510,8 @@ function generateMonitoringDivs(graphs, id_prefix){
function plot_graph(data,context,id_prefix,info){
var labels = info.monitor_resources;
var humanize = info.humanize_figures ? humanize_size : function(val){return val};
var humanize = info.humanize_figures ?
humanize_size : function(val){ return val };
var labels_arr = labels.split(',');
var id_suffix = labels.replace(/,/g,'_');
var series = [];
@ -518,11 +526,11 @@ function plot_graph(data,context,id_prefix,info){
};
var options = {
legend : { show : true,
legend : { show : true,
noColumns: labels_arr.length,
container: $('#legend_'+id_suffix)
},
xaxis : { mode: "time",
xaxis : { mode: "time",
timeformat: "%h:%M"
},
yaxis : { labelWidth: 40,
@ -536,10 +544,79 @@ function plot_graph(data,context,id_prefix,info){
$.plot($('#'+id, context),series,options);
}
//Enables showing full information on this type of fields on
//mouse hover
function shortenedInfoFields(context){
$('.shortened_info',context).live("mouseenter",function(e){
var full_info = $(this).next();
var top,left;
top = (e.pageY-15)+"px";
left = (e.pageX+15)+"px";
full_info.css({"top":top,"left":left});
full_info.fadeIn();
});
$('.shortened_info',context).live("mouseleave",function(e){
$(this).next().fadeOut();
});
}
function setupTemplateUpdateDialog(){
//Append to DOM
$('div#dialogs').append('<div id="template_update_dialog" title="Update template"></div>');
//Put HTML in place
$('#template_update_dialog').html(
'<form action="javascript:alert(\'js error!\');">\
<h3 style="margin-bottom:10px;">Update the template here:</h3>\
<fieldset style="border-top:none;">\
<label for="template_update_select">Select a template:</label>\
<select id="template_update_select" name="template_update_select"></select>\
<div class="clear"></div>\
<textarea id="template_update_textarea" style="width:100%; height:14em;">Select a template</textarea>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="template_update_button" value="">\
Update\
</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>');
$('#template_update_dialog').dialog({
autoOpen:false,
width:700,
modal:true,
height:410,
resizable:false,
});
$('#template_update_dialog button').button();
$('#template_update_dialog #template_update_select').live("change",function(){
var id = $(this).val();
var resource = $('#template_update_dialog #template_update_button').val();
$('#template_update_dialog #template_update_textarea').val("Loading...");
Sunstone.runAction(resource+".fetch_template",id);
});
$('#template_update_dialog #template_update_button').click(function(){
var new_template = $('#template_update_dialog #template_update_textarea').val();
var id = $('#template_update_dialog #template_update_select').val();
var resource = $(this).val();
Sunstone.runAction(resource+".update",id,new_template);
$('#template_update_dialog').dialog('close');
return false;
});
}
//functions that used as true and false conditions for testing mainly
function True(){
return true;
}
function False(){
return false;
}
}

View File

@ -21,7 +21,7 @@ var spinner = '<img src="/images/ajax-loader.gif" alt="retrieving" class="loadin
//Sunstone configuration is formed by predifined "actions", main tabs
//and "info_panels". Each tab has "content" and "buttons". Each
//and "info_panels". Each tab has "content" and "buttons". Each
//"info_panel" has "tabs" with "content".
var SunstoneCfg = {
"actions" : {},
@ -32,29 +32,29 @@ var SunstoneCfg = {
/* Public plugin interface */
var Sunstone = {
//Adds a predifined action
"addAction" : function (action_name,action_obj) {
SunstoneCfg["actions"][action_name] = action_obj;
},
//Replaces a predefined action
"updateAction" : function(action_name,action_obj) {
SunstoneCfg["actions"][action_name] = action_obj;
},
//Deletes a predefined action.
"removeAction" : function(action_name) {
delete SunstoneCfg["actions"][action_name];
},
//Adds several actions encapsulated in an js object.
"addActions" : function(actions) {
for (action in actions){
Sunstone.addAction(action,actions[action]);
}
}
},
//Adds a new main tab. Refreshes the dom if wanted.
"addMainTab" : function(tab_id,tab_obj,refresh) {
SunstoneCfg["tabs"][tab_id] = tab_obj;
@ -62,7 +62,7 @@ var Sunstone = {
insertTab(tab_id);
}
},
//Updates the content of an info tab and refreshes the DOM if wanted.
"updateMainTabContent" : function(tab_id,content_arg,refresh){
SunstoneCfg["tabs"][tab_id]["content"]=content_arg;
@ -70,7 +70,7 @@ var Sunstone = {
$('div#'+tab_id).html(content_arg);
}
},
//Replaces the buttons of an info tab and regenerates them if wanted.
"updateMainTabButtons" : function(tab_id,buttons_arg,refresh){
SunstoneCfg["tabs"][tab_id]["buttons"]=buttons_arg;
@ -79,7 +79,7 @@ var Sunstone = {
insertButtonsInTab(tab_id);
}
},
//Removes a tab and refreshes the DOM
"removeMainTab" : function(tab_id,refresh) {
delete SunstoneCfg["tabs"][tab_id];
@ -88,27 +88,27 @@ var Sunstone = {
$('ul#navigation li#li_'+tab_id).remove();
}
},
//Adds a new info panel
"addInfoPanel" : function(panel_name, panel_obj){
SunstoneCfg["info_panels"][panel_name]=panel_obj;
},
//Replaces an existing info panel
"updateInfoPanel" : function(panel_name,panel_obj){
SunstoneCfg["info_panels"][panel_name]=panel_obj;
},
//Removes an info panel
"removeInfoPanel" : function(panel_name){
delete SunstoneCfg["info_panels"][panel_name];
},
//Makes an info panel content pop up in the screen.
"popUpInfoPanel" : function(panel_name, selected_tab){
popDialog(Sunstone.getInfoPanelHTML(panel_name, selected_tab));
},
//Generates and returns the HTML div element for an info panel, with
//Jquery tabs.
"getInfoPanelHTML" : function(panel_name,selected_tab){
@ -116,53 +116,53 @@ var Sunstone = {
var tabs = SunstoneCfg["info_panels"][panel_name];
var tab=null;
for (tab_name in tabs){
tab=tabs[tab_name];
$('ul',info_panel).append('<li><a href="#'+tab_name+'">'+tab.title+'</a></li>');
info_panel.append('<div id="'+tab_name+'">'+tab.content+'</div>');
tab=tabs[tab_name];
$('ul',info_panel).append('<li><a href="#'+tab_name+'">'+tab.title+'</a></li>');
info_panel.append('<div id="'+tab_name+'">'+tab.content+'</div>');
}
if (selected_tab){
return info_panel.tabs({selected: selected_tab});
}
return info_panel.tabs({selected: 0});
},
//adds a tab to an info panel.
"addInfoPanelTab" : function(panel_name, panel_tab_id, panel_tab_obj){
SunstoneCfg["info_panels"][panel_name][panel_tab_id] = panel_tab_obj;
},
//Replaces a tab from an info panel. Refreshes the DOM if wanted.
"updateInfoPanelTab" : function(panel_name, panel_tab_id,
panel_tab_obj, refresh){
"updateInfoPanelTab" : function(panel_name, panel_tab_id,
panel_tab_obj, refresh){
SunstoneCfg["info_panels"][panel_name][panel_tab_id] = panel_tab_obj;
if (refresh){
var tab_content = panel_tab_obj.content;
$('div#'+panel_name+' div#'+panel_tab_id).html(tab_content);
}
},
//Removes a tab from an info panel configuration.
"removeInfoPanelTab" : function(panel_name,panel_tab_id){
delete SunstoneCfg["info_panels"][panel_name][panel_tab_id];
},
//Runs a predefined action. Wraps the calls to opennebula.js and
//can be use to run action depending on conditions and notify them
//if desired.
"runAction" : function(action, data_arg, extra_param){
var actions = SunstoneCfg["actions"];
if (!actions[action]){
notifyError("Action "+action+" not defined");
return;
}
var action_cfg = actions[action];
var notify = action_cfg.notify;
var condition = action_cfg["condition"];
//Is the condition to run the action met?
//Should we inform if it is not met?
if (condition && !condition()){
@ -171,107 +171,113 @@ var Sunstone = {
}
return;
}
var call = action_cfg["call"];
var callback = action_cfg["callback"];
var err = action_cfg["error"];
//Time to close any confirmation dialogs, as the execution may have
//come from them.
$('div#confirm_with_select_dialog').dialog("close");
$('div#confirm_dialog').dialog("close");
//We ease the use of:
// * "create" calls to opennebula.js
// * "single" element calls to opennebula.js
// * "list" (get the pool of elements) calls to opennebula.js
// * "monitor_global" (returns monitoring information from a pool of elements
// * "monitor_single" (returns monitoring information from 1 element to create graphs)
// * "monitor_global" (returns monitoring info from a pool of elements
// * "monitor_single" (returns monitoring info from 1 element)
// * "multiple" - actions to be run on a given list of elements
// (with maybe an extra parameter).
// * The default actions. Simple call the the pre-defined "call"
// function with an extraparam if defined.
switch (action_cfg.type){
case "create":
case "register":
call({data:data_arg, success: callback, error:err});
break;
case "single":
call({data:{id:data_arg}, success: callback,error:err});
break;
case "list":
call({success: callback, error:err});
break;
case "monitor_global":
call({timeout: true, success: callback, error:err, data: {monitor: data_arg}});
break;
case "monitor":
case "monitor_single":
call({timeout: true, success: callback, error:err, data: {id:data_arg, monitor: extra_param}});
break;
case "multiple":
//run on the list of nodes that come on the data
$.each(data_arg,function(){
if (extra_param){
call({data:{id:this,extra_param:extra_param}, success: callback, error: err});
} else {
call({data:{id:this}, success: callback, error:err});
}
case "create":
case "register":
call({data:data_arg, success: callback, error:err});
break;
case "single":
if (extra_param){
call({
data:{
id:data_arg,
extra_param:extra_param
},
success: callback,error:err
});
break;
default:
//This action is complemente handled by the "call" function.
} else {
call({data:{id:data_arg}, success: callback,error:err});
};
break;
case "list":
call({success: callback, error:err});
break;
case "monitor_global":
call({
timeout: true,
success: callback,
error:err,
data: {monitor: data_arg}});
break;
case "monitor":
case "monitor_single":
call({
timeout: true,
success: callback,
error:err,
data: {id:data_arg, monitor: extra_param}});
break;
case "multiple":
//run on the list of nodes that come on the data
$.each(data_arg,function(){
if (extra_param){
call({
data:{
id:this,
extra_param:extra_param
},
success: callback,
error: err});
} else {
call({
data:{id:this},
success: callback,
error:err});
}
});
break;
default:
//This action is complemente handled by the "call" function.
//we pass any data if present.
if (data_arg && extra_param) {call(data_arg,extra_param);}
else if (data_arg) {call(data_arg);}
else {call();}
if (data_arg && extra_param) {call(data_arg,extra_param);}
else if (data_arg) {call(data_arg);}
else {call();}
}
//notify submission
if (notify) {
notifySubmit(action,data_arg,extra_param);
}
},
//Runs a predefined action on the selected nodes of a datatable.
//Optionally they are run with an extra_parameter.
//If no datatable is provided, it simply runs the action.
//~ "runActionOnDatatableNodes": function(action,dataTable,extra_param){
//~ if (dataTable != null){
//~
//~ //Which rows of the datatable are checked?
//~ var nodes = $('input:checked',dataTable.fnGetNodes());
//~ var data = [];
//~ $.each(nodes,function(){
//~ data.push($(this).val());
//~ });
//~ Sunstone.runAction(action,data,extra_param);
//~
//~ } else {
//~ Sunstone.runAction(action,extra_param);
//~ };
//~ },
//~
//returns a button object from the desired tab
"getButton" : function(tab_id,button_name){
var button = null;
var buttons = SunstoneCfg["tabs"][tab_id]["buttons"];
button = buttons[button_name];
//not found, is it in the list then?
if (!button && buttons["action_list"])
{
button = buttons["action_list"]["actions"][button_name];
}
return button;
var button = null;
var buttons = SunstoneCfg["tabs"][tab_id]["buttons"];
button = buttons[button_name];
//not found, is it in the list then?
if (!button && buttons["action_list"])
{
button = buttons["action_list"]["actions"][button_name];
}
return button;
} //end sunstone methods
};
@ -280,55 +286,61 @@ var Sunstone = {
$(document).ready(function(){
readCookie();
setLogin();
//Insert the tabs in the DOM and their buttons.
insertTabs();
insertButtons();
//Enhace the look of select buttons
initListButtons();
//Prepare the standard confirmation dialogs
setupConfirmDialogs();
//This dialog is shared to update templates
setupTemplateUpdateDialog();
//Listen for .action_buttons
//An action buttons runs a predefined action. If it has type
//An action buttons runs a predefined action. If it has type
//"multiple" it runs that action on the elements of a datatable.
$('.action_button').live("click",function(){
var table = null;
var value = $(this).attr("value");
var action = SunstoneCfg["actions"][value];
if (!action) { notifyError("Action "+value+" not defined."); return false;};
if (!action) {
notifyError("Action "+value+" not defined.");
return false;
};
switch (action.type){
case "multiple": //find the datatable
var nodes = action.elements();
Sunstone.runAction(value,nodes);
break;
default:
Sunstone.runAction(value);
case "multiple": //find the datatable
var nodes = action.elements();
Sunstone.runAction(value,nodes);
break;
default:
Sunstone.runAction(value);
}
return false;
});
//Listen .confirm_buttons. These buttons show a confirmation dialog
//before running the action.
$('.confirm_button').live("click",function(){
popUpConfirmDialog(this);
return false;
});
//Listen .confirm_buttons. These buttons show a confirmation dialog
//with a select box before running the action.
$('.confirm_with_select_button').live("click",function(){
popUpConfirmWithSelectDialog(this);
return false;
});
//Jquery-enhace the buttons in the DOM
$('button').button();
//Close overlay dialogs when clicking outside of them.
$(".ui-widget-overlay").live("click", function (){
$("div:ui-dialog:visible").dialog("close");
@ -338,10 +350,10 @@ $(document).ready(function(){
$('*:not(.action_list,.list_button)').click(function(){
$('.action_list:visible').hide();
});
//Start with the dashboard (supposing we have one).
showTab('#dashboard_tab');
});
@ -357,7 +369,7 @@ function readCookie(){
});
}
//sets the user info in the top bar and creates a listner in the
//sets the user info in the top bar and creates a listner in the
//signout button
function setLogin(){
//This two variables can be used anywhere
@ -366,10 +378,11 @@ function setLogin(){
$("#user").html(username);
$("#logout").click(function(){
OpenNebula.Auth.logout({success:function(){
window.location.href = "/login";
}
});
OpenNebula.Auth.logout({
success:function(){
window.location.href = "/login";
}
});
return false;
});
}
@ -393,7 +406,7 @@ function insertTab(tab_name){
if (condition && !condition()) {return;}
$("div.inner-center").append('<div id="'+tab_name+'" class="tab"></div>');
$('div#'+tab_name).html(tab_info.content);
$('ul#navigation').append('<li id="li_'+tab_name+'"><a href="#'+tab_name+'">'+tab_info.title+'</a></li>');
}
@ -412,11 +425,11 @@ function insertButtonsInTab(tab_name){
var button_code="";
var sel_obj=null;
var condition=null;
//Check if we have included an appropiate space our tab to
//insert them (an .action_blocks div)
if ($('div#'+tab_name+' div.action_blocks').length){
//for every button defined for this tab...
for (button_name in buttons){
button_code = "";
@ -424,7 +437,7 @@ function insertButtonsInTab(tab_name){
condition = button.condition;
//if we meet the condition we proceed. Otherwise we skip it.
if (condition && !condition()) { continue; }
//depending on the type of button we generate different
//code. There are 4 possible types:
/*
@ -434,7 +447,7 @@ function insertButtonsInTab(tab_name){
* default: generally buttons have the "<type>_button" class.
*/
switch (button.type) {
case "select":
case "select":
button_code = '<select class="multi_action_slct">';
//for each subbutton in the list we add an option to the select.
for (sel_name in button.actions){
@ -446,89 +459,84 @@ function insertButtonsInTab(tab_name){
};
button_code += '</select>';
break;
case "image":
case "image":
button_code = '<a href="#" class="action_button" value="'+button_name+'"><img class="image_button" src="'+button.img+'" alt="'+button.text+'" /></a>';
break;
case "create_dialog":
case "create_dialog":
button_code = '<button class="'+button.type+'_button action_button top_button" value="'+button_name+'">'+button.text+'</button>';
break;
default:
default:
button_code = '<button class="'+button.type+'_button top_button" value="'+button_name+'">'+button.text+'</button>';
}
if (button.alwaysActive) {
button_code = $(button_code).addClass("alwaysActive");
}
$('div#'+tab_name+' .action_blocks').append(button_code);
}//for each button in tab
$('.top_button').button();
}//if tab exists
}
//Converts selects into buttons which show a list of actions when
//clicked. This lists have two parts, one for the last action run, and
//Converts selects into buttons which show a list of actions when
//clicked. This lists have two parts, one for the last action run, and
//another containing a list of actions that can be folded/unfolded.
function initListButtons(){
//for each multi_action select
$('.multi_action_slct').each(function(){
//prepare replacement buttons
var buttonset = $('<div style="display:inline-block;" class="top_button"></div');
var button1 = $('<button class="last_action_button action_button confirm_button confirm_with_select_button" value="">Previous action</button>').button();
button1.attr("disabled","disabled");
var button2 = $('<button class="list_button" value="">See more</button>').button({
text:false,
icons: { primary: "ui-icon-triangle-1-s" }
});
buttonset.append(button1);
buttonset.append(button2);
buttonset.buttonset();
//prepare list
var options = $('option', $(this));
var list = $('<ul class="action_list"></ul>');
$.each(options,function(){
var classes = $(this).attr("class");
var item = $('<li></li>');
var a = $('<a href="#" class="'+classes+'" value="'+$(this).val()+'">'+$(this).text()+'</a>');
a.val($(this).val());
item.html(a);
list.append(item);
});
list.css({
"display":"none"
});
//replace the select and insert the buttons
$(this).before(buttonset);
$(this).parents('.action_blocks').append(list);
$(this).remove();
//$(this).replaceWith(list);
//for each multi_action select
$('.multi_action_slct').each(function(){
//prepare replacement buttons
var buttonset = $('<div style="display:inline-block;" class="top_button"></div');
var button1 = $('<button class="last_action_button action_button confirm_button confirm_with_select_button" value="">Previous action</button>').button();
button1.attr("disabled","disabled");
var button2 = $('<button class="list_button" value="">See more</button>').button({
text:false,
icons: { primary: "ui-icon-triangle-1-s" }
});
buttonset.append(button1);
buttonset.append(button2);
buttonset.buttonset();
//prepare list
var options = $('option', $(this));
var list = $('<ul class="action_list"></ul>');
$.each(options,function(){
var classes = $(this).attr("class");
var item = $('<li></li>');
var a = $('<a href="#" class="'+classes+'" value="'+$(this).val()+'">'+$(this).text()+'</a>');
a.val($(this).val());
item.html(a);
list.append(item);
});
list.css({
"display":"none"
});
$(this).before(buttonset);
$(this).parents('.action_blocks').append(list);
$(this).remove();
//below the listeners for events on these buttons and list
});
//enable run the last action button
$('.action_list li a').click(function(){
//enable run last action button
var prev_action_button = $('.last_action_button',$(this).parents('.action_blocks'));
prev_action_button.val($(this).val());
prev_action_button.removeClass("confirm_with_select_button");
prev_action_button.removeClass("confirm_button");
prev_action_button.removeClass("action_button");
prev_action_button.addClass($(this).attr("class"));
prev_action_button.button("option","label",$(this).text());
prev_action_button.button("enable");
$(this).parents('ul').hide("blind",100);
//return false;
});
//below the listeners for events on these buttons and list
//enable run the last action button
$('.action_list li a').click(function(){
//enable run last action button
var prev_action_button = $('.last_action_button',$(this).parents('.action_blocks'));
prev_action_button.val($(this).val());
prev_action_button.removeClass("confirm_with_select_button");
prev_action_button.removeClass("confirm_button");
prev_action_button.removeClass("action_button");
prev_action_button.addClass($(this).attr("class"));
prev_action_button.button("option","label",$(this).text());
prev_action_button.button("enable");
$(this).parents('ul').hide("blind",100);
//return false;
});
//Show the list of actions in place
$('.list_button').click(function(){
@ -544,93 +552,90 @@ function initListButtons(){
//Prepares the standard confirm dialogs
function setupConfirmDialogs(){
//add div to the main body if it isn't present.
if (!($('div#confirm_dialog').length)){
$('div#dialogs').append('<div id="confirm_dialog" title="Confirmation of action"></div>');
};
//add the HTML with the standard question and buttons.
$('div#confirm_dialog').html(
'<form action="javascript:alert(\'js error!\');">\
<div id="confirm_tip">You have to confirm this action.</div>\
<br />\
<div id="question">Do you want to proceed?</div>\
<br />\
<div class="form_buttons">\
<button id="confirm_proceed" class="action_button" value="">OK</button>\
<button class="confirm_cancel" value="">Cancel</button>\
</div>\
</form>');
$('div#confirm_dialog').html(
'<form action="javascript:alert(\'js error!\');">\
<div id="confirm_tip">You have to confirm this action.</div>\
<br />\
<div id="question">Do you want to proceed?</div>\
<br />\
<div class="form_buttons">\
<button id="confirm_proceed" class="action_button" value="">OK</button>\
<button class="confirm_cancel" value="">Cancel</button>\
</div>\
</form>');
//prepare the jquery dialog
$('div#confirm_dialog').dialog({
resizable:false,
modal:true,
width:300,
heigth:200,
autoOpen:false
});
$('div#confirm_dialog').dialog({
resizable:false,
modal:true,
width:300,
heigth:200,
autoOpen:false
});
//enhace the button look
$('div#confirm_dialog button').button();
//same for the confirm with select dialog.
if (!($('div#confirm_with_select_dialog').length)){
$('div#dialogs').append('<div id="confirm_with_select_dialog" title="Confirmation of action"></div>');
};
$('div#confirm_with_select_dialog').html(
'<form action="javascript:alert(\'js error!\');">\
<div id="confirm_with_select_tip">You need to select something.</div>\
<select style="margin: 10px 0;" id="confirm_select">\
</select>\
<div class="form_buttons">\
<button id="confirm_with_select_proceed" class="" value="">OK</button>\
<button class="confirm_cancel" value="">Cancel</button>\
</div>\
</form>');
$('div#confirm_with_select_dialog').html(
'<form action="javascript:alert(\'js error!\');">\
<div id="confirm_with_select_tip">You need to select something.</div>\
<select style="margin: 10px 0;" id="confirm_select">\
</select>\
<div class="form_buttons">\
<button id="confirm_with_select_proceed" class="" value="">OK</button>\
<button class="confirm_cancel" value="">Cancel</button>\
</div>\
</form>');
//prepare the jquery dialog
$('div#confirm_with_select_dialog').dialog({
resizable:false,
modal:true,
width:300,
heigth:300,
autoOpen:false
});
$('div#confirm_with_select_dialog').dialog({
resizable:false,
modal:true,
width:300,
heigth:300,
autoOpen:false
});
$('div#confirm_with_select_dialog button').button();
//if a cancel button is pressed, we close the dialog.
$('button.confirm_cancel').click(function(){
$('div#confirm_with_select_dialog').dialog("close");
$('div#confirm_with_select_dialog').dialog("close");
$('div#confirm_dialog').dialog("close");
return false;
});
return false;
});
//when we proceed with a "confirm with select" we need to
//find out if we are running an action with a parametre on a datatable
//items or if its just an action
//items or if its just an action
$('button#confirm_with_select_proceed').click(function(){
var value = $(this).val();
var action = SunstoneCfg["actions"][value];
var param = $('select#confirm_select').val();
if (!action) { notifyError("Action "+value+" not defined."); return false;};
switch (action.type){
case "multiple": //find the datatable
var nodes = action.elements();
Sunstone.runAction(value,nodes,param);
break;
default:
Sunstone.runAction(value,param);
break;
case "multiple": //find the datatable
var nodes = action.elements();
Sunstone.runAction(value,nodes,param);
break;
default:
Sunstone.runAction(value,param);
break;
}
return false;
});
}
//Popup a confirmation dialog.
@ -659,9 +664,7 @@ function popUpConfirmWithSelectDialog(target_elem){
var select_var = button.select();
$('select#confirm_select').html(select_var);
$('div#confirm_with_select_tip').text(tip);
$('button#confirm_with_select_proceed').val(value);
$('div#confirm_with_select_dialog').dialog("open");
}

View File

@ -184,6 +184,11 @@ end
##############################################################################
# GET Resource information
##############################################################################
get '/:resource/:id/template' do
@SunstoneServer.get_template(params[:resource], params[:id])
end
get '/:resource/:id' do
@SunstoneServer.get_resource(params[:resource], params[:id])
end

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>