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

feature #3264: Extend showback support in Sunstone

This commit is contained in:
Daniel Molina 2014-11-07 18:44:36 +01:00
parent 78f6bd613d
commit f04fd92f2f
12 changed files with 205 additions and 138 deletions

View File

@ -312,11 +312,11 @@ module OpenNebula
# part of the Pool. Possible values: INFO_ALL, INFO_GROUP, INFO_MINE
# or user_id
# @param [Hash] options
# @option params [Integer] :start_month First month (+year) to take
# @option params [Integer] :start_year First month (+year) to take
# into account, if no start time is required use -1
# @option params [Integer] :start_month First year (+month) to take
# into account, if no start time is required use -1
# @option params [Integer] :end_month Last month (+year) to take
# @option params [Integer] :end_year Last month (+year) to take
# into account, if no end time is required use -1
# @option params [Integer] :end_month Last year (+month) to take
# into account, if no end time is required use -1
@ -366,11 +366,11 @@ module OpenNebula
# part of the Pool. Possible values: INFO_ALL, INFO_GROUP, INFO_MINE
# or user_id
# @param [Hash] options
# @option params [Integer] :start_month First month (+year) to take
# @option params [Integer] :start_year First month (+year) to take
# into account, if no start time is required use -1
# @option params [Integer] :start_month First year (+month) to take
# into account, if no start time is required use -1
# @option params [Integer] :end_month Last month (+year) to take
# @option params [Integer] :end_year Last month (+year) to take
# into account, if no end time is required use -1
# @option params [Integer] :end_month Last year (+month) to take
# into account, if no end time is required use -1

View File

@ -51,6 +51,8 @@ tabs:
panel_tabs:
user_info_tab: true
user_quotas_tab: true
user_accounting_tab: true
user_showback_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
@ -74,7 +76,11 @@ tabs:
User.delete: true
groups-tab:
panel_tabs:
group_info_tab: true
group_quotas_tab: true
group_providers_tab: true
group_accounting_tab: true
group_shoback_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID

View File

@ -51,6 +51,8 @@ tabs:
panel_tabs:
user_info_tab: true
user_quotas_tab: true
user_accounting_tab: true
user_showback_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
@ -73,7 +75,11 @@ tabs:
User.delete: true
groups-tab:
panel_tabs:
group_info_tab: true
group_quotas_tab: true
group_providers_tab: true
group_accounting_tab: true
group_shoback_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID

View File

@ -51,6 +51,8 @@ tabs:
panel_tabs:
user_info_tab: true
user_quotas_tab: true
user_accounting_tab: true
user_showback_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
@ -74,7 +76,11 @@ tabs:
User.delete: true
groups-tab:
panel_tabs:
group_info_tab: true
group_quotas_tab: true
group_providers_tab: true
group_accounting_tab: true
group_shoback_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID

View File

@ -395,12 +395,16 @@ class SunstoneServer < CloudServer
pool = VirtualMachinePool.new(@client)
filter_flag = options[:userfilter] ? options[:userfilter].to_i : VirtualMachinePool::INFO_ALL
start_time = options[:start_time] ? options[:start_time].to_i : -1
end_time = options[:end_time] ? options[:end_time].to_i : -1
start_month = options[:start_month] ? options[:start_month].to_i : -1
start_year = options[:start_year] ? options[:start_year].to_i : -1
end_month = options[:end_month] ? options[:end_month].to_i : -1
end_year = options[:end_year] ? options[:end_year].to_i : -1
acct_options = {
:start_time => start_time,
:end_time => end_time,
:start_month => start_month,
:start_year => start_year,
:end_month => end_month,
:end_year => end_year,
:group => options[:group]
}

View File

@ -361,15 +361,6 @@ function setupConfigDialog() {
});
}
function tr(str){
var tmp = locale[str];
if ( tmp == null || tmp == "" ) {
//console.debug("Missing translation: "+str);
tmp = str;
}
return tmp;
};
function updateUserConfigInfo(request,user_json) {
var info = user_json.USER;

View File

@ -734,10 +734,17 @@ function updateGroupInfo(request,group){
content: '<div id="group_accounting"></div>'
};
var showback_tab = {
title: tr("Showback"),
icon: "fa-money",
content: '<div id="group_showback"></div>'
};
Sunstone.updateInfoPanelTab("group_info_panel","group_info_tab",info_tab);
Sunstone.updateInfoPanelTab("group_info_panel","group_quotas_tab",quotas_tab);
Sunstone.updateInfoPanelTab("group_info_panel","group_providers_tab",providers_tab);
Sunstone.updateInfoPanelTab("group_info_panel","group_accouning_tab",accounting_tab);
Sunstone.updateInfoPanelTab("group_info_panel","group_accounting_tab",accounting_tab);
Sunstone.updateInfoPanelTab("group_info_panel","group_showback_tab",showback_tab);
Sunstone.popUpInfoPanel("group_info_panel", 'groups-tab');
$("#add_rp_button", $("#group_info_panel")).click(function(){
@ -753,6 +760,10 @@ function updateGroupInfo(request,group){
{ fixed_group: info.ID,
init_group_by: "user" });
showbackGraphs(
$("#group_showback","#group_info_panel"),
{ fixed_group: info.ID });
setupQuotasPanel(info,
"#group_info_panel",
Config.isTabActionEnabled("groups-tab", "Group.quotas_dialog"),

View File

@ -1206,6 +1206,21 @@ var provision_manage_vdc = '<div id="provision_manage_vdc" class="hidden section
'</div>'+
'</div>'+
'<br>'+
'<div class="row">'+
'<div class="large-11 large-centered columns">'+
'<h3 class="subheader text-right">'+
'<span class="left">'+
tr("VDC Showback")+
'</span>'+
'</h3>'+
'</div>'+
'</div>'+
'<br>'+
'<div class="row">'+
'<div id="provision_info_vdc_group_showback" class="large-10 large-centered columns">'+
'</div>'+
'</div>'+
'<br>'+
'<div class="row">'+
'<div class="large-11 large-centered columns">'+
'<h3 class="subheader text-right">'+
@ -2007,18 +2022,23 @@ function generate_provision_instance_type_accordion(context, capacity) {
'<div class="row">'+
'<div class="large-12 large-centered columns">'+
'<div class="row text-center">'+
'<div class="large-6 columns">'+
'<div class="large-4 columns">'+
'<span class="cpu_value" style="color: #777; font-size:60px">'+capacity.CPU+'</span>'+
'<br>'+
'<span style="color: #999;">'+tr("CPU")+'</span>'+
'</div>'+
'<div class="large-6 columns">'+
'<div class="large-4 columns">'+
'<span class="memory_value" style="color: #777; font-size:60px">'+memory_value+'</span>'+
' '+
'<span class="memory_unit" style="color: #777; font-size:30px">'+memory_unit+'</span>'+
'<br>'+
'<span style="color: #999;">'+tr("MEMORY")+'</span>'+
'</div>'+
'<div class="large-4 columns provision_create_template_cost_div hidden">'+
'<span class="cost_value" style="color: #777; font-size:60px"></span>'+
'<br>'+
'<span style="color: #999;">'+tr("COST")+' / ' + tr("HOUR") + '</span>'+
'</div>'+
'</div>'+
'</div>'+
'</div>'+
@ -2061,6 +2081,25 @@ function generate_provision_instance_type_accordion(context, capacity) {
'</div>'+
'<br>');
var cost = 0;
if (capacity.CPU_COST || capacity.MEMORY_COST) {
$(".provision_create_template_cost_div").show();
if (capacity.CPU && capacity.CPU_COST) {
cost += capacity.CPU * capacity.CPU_COST
$(".cost_value").data("CPU_COST", capacity.CPU_COST);
}
if (capacity.MEMORY && capacity.MEMORY_COST) {
cost += capacity.MEMORY * capacity.MEMORY_COST
$(".cost_value").data("MEMORY_COST", capacity.MEMORY_COST);
}
$(".cost_value").html(cost);
} else {
$(".provision_create_template_cost_div").hide();
}
provision_instance_type_accordion_id += 1;
var provision_instance_types_datatable = $('.provision_instance_types_table', context).dataTable({
@ -2153,6 +2192,18 @@ function generate_provision_instance_type_accordion(context, capacity) {
$(".memory_value", context).html(memory_value);
$(".memory_unit", context).html(memory_unit);
var cost = 0;
if ($(".cost_value").data("CPU_COST")) {
cost += $(this).attr("cpu") * $(".cost_value").data("CPU_COST")
}
if ($(".cost_value").data("MEMORY_COST")) {
cost += $(this).attr("memory") * $(".cost_value").data("MEMORY_COST")
}
$(".cost_value").html(cost);
$('.accordion a', context).first().trigger("click");
})
@ -2776,6 +2827,10 @@ function show_provision_group_info_callback(request, response) {
{ fixed_group: info.ID,
init_group_by: "user" });
showbackGraphs(
$("#provision_info_vdc_group_showback", context),
{ fixed_group: info.ID });
$("#acct_placeholder", context).hide();
}
@ -5081,6 +5136,9 @@ function setup_provision_user_info(context) {
'<span class="provision_vdc_user_info_show_acct button medium radius" data-tooltip title="'+tr("User Accounting")+'" style="margin-right: 10px">'+
'<i class="fa fa-bar-chart-o fa-lg"></i>'+
'</span>'+
'<span class="provision_vdc_user_info_show_showback button medium radius" data-tooltip title="'+tr("User Showback")+'" style="margin-right: 10px">'+
'<i class="fa fa-money fa-lg"></i>'+
'</span>'+
'</li>'+
'<li class="provision-bullet-item text-left">'+
'</li>')
@ -5217,6 +5275,19 @@ function setup_provision_user_info(context) {
'</h2>')
})
context.on("click", ".provision_vdc_user_info_show_showback", function(){
$(".provision_vdc_info_container", context).html("");
showbackGraphs(
$(".provision_vdc_info_container", context),
{ fixed_user: $(".provision_info_vdc_user", context).attr("opennebula_id")});
$(".provision_vdc_info_container", context).prepend(
'<h2 class="subheader">'+
$(".provision_info_vdc_user", context).attr("uname") + ' ' + tr("Showback")+
'</h2>')
})
context.on("click", ".provision_vdc_user_delete_confirm_button", function(){
$(".provision_vdc_user_confirm_action", context).html(
'<div data-alert class="alert-box secondary radius">'+

View File

@ -827,7 +827,6 @@ function generate_capacity_tab_content() {
'<input type="text" id="vcenter_template_uuid" name="name"/>'+
'</div>'+
'</div>'+
'<br>'+
generate_capacity_inputs();
return html;
@ -839,51 +838,69 @@ function generate_capacity_inputs() {
'<input type="hidden" id="MEMORY" name="memory" />'+
'</div>'+
'<div class="row">'+
'<div class="large-2 columns">'+
'<label class="inline" for="MEMORY">'+tr("Memory")+'\
<span class="tip right">'+tr("Amount of RAM required for the VM, in Megabytes.")+'</span>\
'<div class="large-7 columns">'+
'<label class="" for="MEMORY">'+tr("Memory")+'\
<span class="tip ">'+tr("Amount of RAM required for the VM, in Megabytes.")+'</span>\
</label>'+
'</div>'+
'<div class="large-6 columns">'+
'<div id="memory_slider" class="large-7 columns">'+
'<div class="large-8 columns">'+
'<div id="memory_slider" class="large-7 columns">'+
'</div>'+
'</div>'+
'</div>'+
'<div class="large-2 columns">'+
'<input type="text" id="MEMORY_TMP" name="memory_tmp" size="4" />'+
'</div>'+
'<div class="large-2 columns">'+
'<select id="memory_unit" name="MEMORY_UNIT">'+
'<option value="MB">'+tr("MB")+'</option>'+
'<option value="GB">'+tr("GB")+'</option>'+
'</select>'+
'</div>'+
'</div>'+
'<div class="row">'+
'<div class="large-2 columns">'+
'<label class="inline" for="CPU">'+tr("CPU")+'\
<span class="tip right">'+tr("Percentage of CPU divided by 100 required for the Virtual Machine. Half a processor is written 0.5.")+'</span>\
</label>'+
'</div>'+
'<div class="large-8 columns">'+
'<div id="cpu_slider">'+
'<div class="large-2 columns">'+
'<input type="text" id="MEMORY_TMP" name="memory_tmp" size="4" />'+
'</div>'+
'<div class="large-2 columns">'+
'<select id="memory_unit" name="MEMORY_UNIT">'+
'<option value="MB">'+tr("MB")+'</option>'+
'<option value="GB">'+tr("GB")+'</option>'+
'</select>'+
'</div>'+
'</div>'+
'<div class="large-2 columns vm_param">'+
'<input type="text" id="CPU" name="cpu"/>'+
'<label for="MEMORY_COST">'+tr("Cost")+'\
<span class="tip">'+tr("Cost of each MB per hour")+'</span>\
</label>'+
'<input type="text" id="MEMORY_COST" name="name"/>'+
'</div>'+
'<div class="large-3 columns">'+
'</div>'+
'</div>'+
'<div class="row">'+
'<div class="large-7 columns">'+
'<label class="" for="CPU">'+tr("CPU")+'\
<span class="tip">'+tr("Percentage of CPU divided by 100 required for the Virtual Machine. Half a processor is written 0.5.")+'</span>\
</label>'+
'<div class="large-10 columns">'+
'<div id="cpu_slider">'+
'</div>'+
'</div>'+
'<div class="large-2 columns vm_param">'+
'<input type="text" id="CPU" name="cpu"/>'+
'</div>'+
'</div>'+
'<div class="large-2 columns vm_param">'+
'<label for="CPU_COST">'+tr("Cost")+'\
<span class="tip">'+tr("Cost of each CPU per hour")+'</span>\
</label>'+
'<input type="text" id="CPU_COST" name="name"/>'+
'</div>'+
'<div class="large-3 columns">'+
'</div>'+
'</div>'+
'<div class="row">' +
'<div class="large-2 columns">'+
'<label class="inline" for="VCPU">'+tr("VCPU")+'\
<span class="tip right">'+tr("Number of virtual cpus. This value is optional, the default hypervisor behavior is used, usually one virtual CPU.")+'</span>\
'<div class="large-7 columns">'+
'<label class="" for="VCPU">'+tr("VCPU")+'\
<span class="tip">'+tr("Number of virtual cpus. This value is optional, the default hypervisor behavior is used, usually one virtual CPU.")+'</span>\
</label>'+
'</div>'+
'<div class="large-8 columns">'+
'<div id="vcpu_slider">'+
'<div class="large-10 columns">'+
'<div id="vcpu_slider">'+
'</div>'+
'</div>'+
'<div class="large-2 columns vm_param">'+
'<input type="text" id="VCPU" name="vcpu"/>'+
'</div>'+
'</div>'+
'<div class="large-2 columns vm_param">'+
'<input type="text" id="VCPU" name="vcpu"/>'+
'<div class="large-5 columns">'+
'</div>'+
'</div>'

View File

@ -607,9 +607,16 @@ function updateUserInfo(request,user){
content: '<div id="user_accounting"></div>'
};
var showback_tab = {
title: tr("Showback"),
icon: "fa-money",
content: '<div id="user_showback"></div>'
};
Sunstone.updateInfoPanelTab("user_info_panel","user_info_tab",info_tab);
Sunstone.updateInfoPanelTab("user_info_panel","user_quotas_tab",quotas_tab);
Sunstone.updateInfoPanelTab("user_info_panel","user_accouning_tab",accounting_tab);
Sunstone.updateInfoPanelTab("user_info_panel","user_accounting_tab",accounting_tab);
Sunstone.updateInfoPanelTab("user_info_panel","user_showback_tab",showback_tab);
//Sunstone.updateInfoPanelTab("user_info_panel","user_acct_tab",acct_tab);
Sunstone.popUpInfoPanel("user_info_panel", 'users-tab');
@ -618,6 +625,10 @@ function updateUserInfo(request,user){
{ fixed_user: info.ID,
init_group_by: "vm" });
showbackGraphs(
$("#user_showback","#user_info_panel"),
{ fixed_user: info.ID });
setupQuotasPanel(info,
"#user_info_panel",
Config.isTabActionEnabled("users-tab", "User.quotas_dialog"),

View File

@ -2366,13 +2366,15 @@ function printCapacity(vm_info){
html += '\
<div class="row">\
<div class="large-6 columns">\
<div class="large-9 columns">\
<table class="info_table dataTable extended_table">\
<thead>\
<tr>\
<th>'+tr("CPU")+'</th>\
<th>'+tr("VCPU")+'</th>\
<th>'+tr("MEMORY")+'</th>\
<th>'+tr("Cost / CPU")+'</th>\
<th>'+tr("Cost / MByte")+'</th>\
<th></th>\
</tr>\
</thead>\
@ -2381,6 +2383,8 @@ function printCapacity(vm_info){
<td id="cpu_info">' + vm_info.TEMPLATE.CPU + '</td>\
<td id="vcpu_info">' + (vm_info.TEMPLATE.VCPU ? vm_info.TEMPLATE.VCPU : '-') + '</td>\
<td id="memory_info" one_value="'+vm_info.TEMPLATE.MEMORY+'">' + humanize_size_from_mb(vm_info.TEMPLATE.MEMORY) + '</td>\
<td id="cpu_cost_info">' + (vm_info.TEMPLATE.CPU_COST ? vm_info.TEMPLATE.CPU_COST : '-') + '</td>\
<td id="memory_cost_info" >' + (vm_info.TEMPLATE.MEMORY_COST ? vm_info.TEMPLATE.MEMORY_COST : '-') + '</td>\
<td>';
if (Config.isTabActionEnabled("vms-tab", "VM.resize")) {

View File

@ -4771,14 +4771,6 @@ function showbackGraphs(div, opt){
div.html(
'<div class="row">\
<div id="showback_start_time_container" class="left columns">\
<label for="showback_start_time">'+tr("Start time")+'</label>\
<input id="showback_start_time" type="date" placeholder="2013/12/30"/>\
</div>\
<div id="showback_end_time_container" class="left columns">\
<label for="showback_end_time">'+tr("End time")+'</label>\
<input id="showback_end_time" type="date" placeholder="'+tr("Today")+'"/>\
</div>\
<div id="showback_owner_container" class="left columns">\
<label for="showback_owner">' + tr("Filter") + '</label>\
<div class="row">\
@ -4794,11 +4786,10 @@ function showbackGraphs(div, opt){
</div>\
</div>\
</div>\
<div id="showback_button_container" class="left columns" style="margin-top: 15px">\
<button class="button radius success large-12" id="showback_submit" type="button">'+tr("Get Showback")+'</button>\
<div id="showback_button_container" class="left columns">\
<button class="button radius success right" id="showback_submit" type="button">'+tr("Get Showback")+'</button>\
</div>\
</div>\
<br>\
<div id="showback_placeholder">\
<div class="row">\
<div class="large-8 large-centered columns">\
@ -4836,6 +4827,7 @@ function showbackGraphs(div, opt){
<tbody id="tbody_showback_datatable">\
</tbody>\
</table>\
<span class="label secondary radius showback_select_a_row">'+tr("Select a row to get detailed information of the month")+'</span>\
</div>\
<div class="large-6 columns">\
<div class="large-12 columns centered graph" id="showback_graph" style="height: 200px;">\
@ -4852,6 +4844,7 @@ function showbackGraphs(div, opt){
<tr>\
<th>'+tr("ID")+'</th>\
<th>'+tr("Name")+'</th>\
<th>'+tr("Owner")+'</th>\
<th>'+tr("Hours")+'</th>\
<th>'+tr("Cost")+'</th>\
</tr>\
@ -4867,29 +4860,6 @@ function showbackGraphs(div, opt){
opt = {};
}
//--------------------------------------------------------------------------
// Set column width
//--------------------------------------------------------------------------
var n_columns = 3; // start, end time, button
if (opt.fixed_user == undefined && opt.fixed_group == undefined){
n_columns += 1; //acct_owner_container
}
if (n_columns > 4){
// In this case the first row will have 4 inputs, and the
// get accounting button will overflow to the second row
n_columns = 4;
}
var width = parseInt(12 / n_columns);
$("#showback_start_time_container", div).addClass("large-"+width);
$("#showback_end_time_container", div).addClass("large-"+width);
$("#showback_owner_container", div).addClass("large-"+width);
$("#showback_button_container", div).addClass("large-"+width);
//--------------------------------------------------------------------------
// VM owner: all, group, user
//--------------------------------------------------------------------------
@ -4925,17 +4895,15 @@ function showbackGraphs(div, opt){
"iDisplayLength": 6,
"sDom": "t<'row collapse'<'small-6 columns'><'small-6 columns'p>>",
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ['_all'] },
{ "bVisible": false, "aTargets": [0,1,2]}
]
});
showback_dataTable.fnSort( [ [0, "desc"] ] );
showback_vms_dataTable = $("#showback_vms_datatable",div).dataTable({
"bSortClasses" : false,
"bDeferRender": true,
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ['_all'] },
]
"bDeferRender": true
});
showback_dataTable.on("click", "tr", function(){
@ -4948,6 +4916,7 @@ function showbackGraphs(div, opt){
$("#showback_vms_title").text($months[month] + " " + year + " " + tr("VMs"))
$(".showback_vms_table").show();
$(".showback_select_a_row").hide();
})
//--------------------------------------------------------------------------
@ -4955,41 +4924,7 @@ function showbackGraphs(div, opt){
//--------------------------------------------------------------------------
$("#showback_submit", div).on("click", function(){
var start_time = -1;
var end_time = -1;
var v = $("#showback_start_time", div).val();
if (v != ""){
start_time = Date.parse(v+' UTC');
if (isNaN(start_time)){
notifyError(tr("Time range start is not a valid date. It must be YYYY/MM/DD"));
return false;
}
// ms to s
start_time = start_time / 1000;
}
var v = $("#showback_end_time", div).val();
if (v != ""){
end_time = Date.parse(v+' UTC');
if (isNaN(end_time)){
notifyError(tr("Time range end is not a valid date. It must be YYYY/MM/DD"));
return false;
}
// ms to s
end_time = end_time / 1000;
}
var options = {
"start_time": start_time,
"end_time": end_time
};
var options = {};
if (opt.fixed_user != undefined){
options.userfilter = opt.fixed_user;
} else if (opt.fixed_group != undefined){
@ -5018,7 +4953,6 @@ function showbackGraphs(div, opt){
OpenNebula.VM.showback({
// timeout: true,
success: function(req, response){
console.log(response)
fillShowback(div, req, response);
},
error: onError,
@ -5053,8 +4987,8 @@ function fillShowback(div, req, response) {
}
}
vms_per_date[showback.YEAR][showback.MONTH].VMS.push([showback.VMID, showback.VMNAME, showback.HOURS, showback.COST]);
vms_per_date[showback.YEAR][showback.MONTH].TOTAL += parseInt(showback.COST);
vms_per_date[showback.YEAR][showback.MONTH].VMS.push([showback.VMID, showback.VMNAME, showback.UNAME, showback.HOURS, showback.COST]);
vms_per_date[showback.YEAR][showback.MONTH].TOTAL += parseFloat(showback.COST);
});
var series = []
@ -5062,7 +4996,7 @@ function fillShowback(div, req, response) {
$.each(vms_per_date, function(year, months){
$.each(months, function(month, value){
series.push([""+year+month, year, month, $months[month] + " " + year, value.TOTAL])
showback_data.push([(new Date(year, month)), value.TOTAL])
showback_data.push([(new Date(year, month)), value.TOTAL.toFixed(2) ])
})
})
@ -5095,17 +5029,23 @@ function fillShowback(div, req, response) {
show: false
},
series: {
lines: {
bars: {
show: true,
lineWidth: 0,
barWidth: 24 * 60 * 60 * 1000 * 20,
fill: true,
align: "center"
align: "left"
}
},
grid: {
borderWidth: 1,
borderColor: "#efefef"
borderColor: "#efefef",
hoverable: true
}
//tooltip: true,
//tooltipOpts: {
// content: "%x"
//}
};
var showback_plot = $.plot($("#showback_graph", div), showback_plot_series, options);