mirror of
https://github.com/OpenNebula/one.git
synced 2025-04-01 06:50:25 +03:00
Bug #4148: Instantiate shows total cost for VMs, services. Including admin view
This commit is contained in:
parent
c3122a2ebb
commit
fffc798cd0
@ -16,6 +16,7 @@
|
||||
|
||||
define(function(require) {
|
||||
var OpenNebulaAction = require('./action');
|
||||
var Config = require('sunstone-config');
|
||||
|
||||
var RESOURCE = "VMTEMPLATE";
|
||||
|
||||
@ -95,7 +96,56 @@ define(function(require) {
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
"cost": function(template) {
|
||||
var cost = 0;
|
||||
var capacity = template.VMTEMPLATE.TEMPLATE;
|
||||
|
||||
var cpuCost = capacity.CPU_COST;
|
||||
var memoryCost = capacity.MEMORY_COST;
|
||||
var diskCost = capacity.DISK_COST;
|
||||
|
||||
if (cpuCost == undefined){
|
||||
cpuCost = Config.onedConf.DEFAULT_COST.CPU_COST;
|
||||
}
|
||||
|
||||
if (memoryCost == undefined){
|
||||
memoryCost = Config.onedConf.DEFAULT_COST.MEMORY_COST;
|
||||
}
|
||||
|
||||
if (diskCost == undefined){
|
||||
diskCost = Config.onedConf.DEFAULT_COST.DISK_COST;
|
||||
}
|
||||
|
||||
if (capacity.CPU) {
|
||||
cost += capacity.CPU * cpuCost;
|
||||
}
|
||||
|
||||
if (capacity.MEMORY) {
|
||||
cost += capacity.MEMORY * memoryCost;
|
||||
}
|
||||
|
||||
if (diskCost != 0) {
|
||||
var template_disk = capacity.DISK;
|
||||
var disks = [];
|
||||
if ($.isArray(template_disk)) {
|
||||
disks = template_disk;
|
||||
} else if (!$.isEmptyObject(template_disk)) {
|
||||
disks = [template_disk];
|
||||
}
|
||||
|
||||
$.each(disks, function(i,disk){
|
||||
if (disk.SIZE) {
|
||||
cost += diskCost * disk.SIZE;
|
||||
}
|
||||
|
||||
if (disk.DISK_SNAPSHOT_TOTAL_SIZE) {
|
||||
cost += diskCost * disk.DISK_SNAPSHOT_TOTAL_SIZE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ define(function(require) {
|
||||
var Notifier = require('utils/notifier');
|
||||
var WizardFields = require('utils/wizard-fields');
|
||||
var UserInputs = require('utils/user-inputs');
|
||||
var Config = require('sunstone-config');
|
||||
|
||||
/*
|
||||
TEMPLATES
|
||||
@ -108,6 +109,8 @@ define(function(require) {
|
||||
|
||||
that.service_template_json = template_json;
|
||||
|
||||
$(".name", context).text(template_json.DOCUMENT.NAME);
|
||||
|
||||
$("#instantiate_service_user_inputs", context).empty();
|
||||
|
||||
UserInputs.serviceTemplateInsert(
|
||||
@ -117,6 +120,8 @@ define(function(require) {
|
||||
n_roles = template_json.DOCUMENT.TEMPLATE.BODY.roles.length;
|
||||
n_roles_done = 0;
|
||||
|
||||
var total_cost = 0;
|
||||
|
||||
$.each(template_json.DOCUMENT.TEMPLATE.BODY.roles, function(index, role){
|
||||
var div_id = "user_input_role_"+index;
|
||||
|
||||
@ -127,13 +132,23 @@ define(function(require) {
|
||||
|
||||
OpenNebulaTemplate.show({
|
||||
data : {
|
||||
id: role.vm_template
|
||||
id: role.vm_template,
|
||||
extended: true
|
||||
},
|
||||
timeout: true,
|
||||
success: function (request, vm_template_json){
|
||||
|
||||
$("#"+div_id, context).empty();
|
||||
|
||||
var cost = OpenNebulaTemplate.cost(vm_template_json);
|
||||
|
||||
if (cost != 0 && Config.isFeatureEnabled("showback")) {
|
||||
total_cost += (cost * role.cardinality);
|
||||
|
||||
$(".total_cost_div", context).show();
|
||||
$(".total_cost_div .cost_value", context).text( (total_cost).toFixed(2) );
|
||||
}
|
||||
|
||||
UserInputs.vmTemplateInsert(
|
||||
$("#"+div_id, context),
|
||||
vm_template_json,
|
||||
|
@ -28,6 +28,13 @@
|
||||
<input type="number" min="1" name="service_n_times" id="service_n_times" value="1">
|
||||
</div>
|
||||
</div>
|
||||
<h5>
|
||||
<span class="name"></span>
|
||||
<span class="total_cost_div" hidden>
|
||||
<small class="cost_value">0.00</small>
|
||||
<small>{{tr "COST"}} / {{tr "HOUR"}}</small>
|
||||
</span>
|
||||
</h5>
|
||||
<div id="instantiate_service_user_inputs">
|
||||
<i class="fa fa-spinner fa-spin"></i>
|
||||
</div>
|
||||
|
@ -63,7 +63,7 @@ define(function(require) {
|
||||
ProvisionFlowsList.show(0);
|
||||
var context = $("#provision_create_flow");
|
||||
$("#flow_name", context).val('');
|
||||
//$(".provision_selected_networks").html("");
|
||||
$(".total_cost_div", context).hide();
|
||||
$(".provision-pricing-table", context).removeClass("selected");
|
||||
},
|
||||
error: Notifier.onError
|
||||
@ -92,6 +92,7 @@ define(function(require) {
|
||||
$(".provision_selected_networks").html("");
|
||||
$(".provision-pricing-table", context).removeClass("selected");
|
||||
$(".alert-box-error", context).hide();
|
||||
$(".total_cost_div", context).hide();
|
||||
|
||||
$('#provision_vm_instantiate_templates_owner_filter').val('all').change();
|
||||
$('#provision_vm_instantiate_template_search').val('').trigger('input');
|
||||
@ -124,63 +125,15 @@ define(function(require) {
|
||||
'</div>'+
|
||||
'</fieldset>');
|
||||
|
||||
var capacity = template_json.VMTEMPLATE.TEMPLATE;
|
||||
var cost = 0;
|
||||
var cost = OpenNebula.Template.cost(template_json);
|
||||
|
||||
var cpuCost = capacity.CPU_COST;
|
||||
var memoryCost = capacity.MEMORY_COST;
|
||||
var diskCost = capacity.DISK_COST;
|
||||
|
||||
if (cpuCost == undefined){
|
||||
cpuCost = Config.onedConf.DEFAULT_COST.CPU_COST;
|
||||
}
|
||||
|
||||
if (memoryCost == undefined){
|
||||
memoryCost = Config.onedConf.DEFAULT_COST.MEMORY_COST;
|
||||
}
|
||||
|
||||
if (diskCost == undefined){
|
||||
diskCost = Config.onedConf.DEFAULT_COST.DISK_COST;
|
||||
}
|
||||
|
||||
if ((cpuCost != 0 || memoryCost != 0 || diskCost != 0) && Config.isFeatureEnabled("showback")) {
|
||||
if ((cost != 0) && Config.isFeatureEnabled("showback")) {
|
||||
$(".provision_create_service_cost_div", context).show();
|
||||
$(".provision_create_service_cost_div", context).data("cost", cost);
|
||||
|
||||
if (capacity.CPU) {
|
||||
cost += capacity.CPU * cpuCost;
|
||||
$(".cost_value", context).data("CPU_COST", cpuCost);
|
||||
}
|
||||
|
||||
if (capacity.MEMORY) {
|
||||
cost += capacity.MEMORY * memoryCost;
|
||||
$(".cost_value", context).data("MEMORY_COST", memoryCost);
|
||||
}
|
||||
|
||||
if (diskCost != 0) {
|
||||
var template_disk = capacity.DISK;
|
||||
var disks = [];
|
||||
if ($.isArray(template_disk)) {
|
||||
disks = template_disk;
|
||||
} else if (!$.isEmptyObject(template_disk)) {
|
||||
disks = [template_disk];
|
||||
}
|
||||
|
||||
$(".cost_value", context).data("DISK_COST", diskCost);
|
||||
|
||||
$.each(disks, function(i,disk){
|
||||
if (disk.SIZE) {
|
||||
cost += diskCost * disk.SIZE;
|
||||
}
|
||||
|
||||
if (disk.DISK_SNAPSHOT_TOTAL_SIZE) {
|
||||
cost += diskCost * disk.DISK_SNAPSHOT_TOTAL_SIZE;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(".provision_create_service_cost_div", context).data("cost", cost)
|
||||
var cost_value = cost*parseInt(role_template.cardinality);
|
||||
$(".cost_value", context).html(cost_value.toFixed(2));
|
||||
_calculateFlowCost();
|
||||
} else {
|
||||
$(".provision_create_service_cost_div", context).hide();
|
||||
}
|
||||
@ -200,6 +153,7 @@ define(function(require) {
|
||||
$( ".cardinality_slider_div", context).on("input", 'input', function() {
|
||||
var cost_value = $(".provision_create_service_cost_div", context).data("cost")*$(this).val();
|
||||
$(".cost_value", context).html(cost_value.toFixed(2));
|
||||
_calculateFlowCost();
|
||||
});
|
||||
} else {
|
||||
$( ".cardinality_slider_div", context).hide();
|
||||
@ -236,7 +190,6 @@ define(function(require) {
|
||||
CapacityInputs.html() +
|
||||
'</fieldset>');
|
||||
|
||||
|
||||
CapacityInputs.setup(context);
|
||||
CapacityInputs.fill(context, element);
|
||||
|
||||
@ -283,6 +236,8 @@ define(function(require) {
|
||||
}
|
||||
|
||||
$(".cost_value", context).html(cost.toFixed(2));
|
||||
|
||||
_calculateCost();
|
||||
};
|
||||
|
||||
if ((cpuCost != 0 || memoryCost != 0) && Config.isFeatureEnabled("showback")) {
|
||||
@ -298,6 +253,38 @@ define(function(require) {
|
||||
}
|
||||
}
|
||||
|
||||
function _calculateCost(){
|
||||
var context = $("#provision_create_vm");
|
||||
|
||||
var capacity_val = parseFloat( $(".provision_create_template_cost_div .cost_value", context).text() );
|
||||
var disk_val = parseFloat( $(".provision_create_template_disk_cost_div .cost_value", context).text() );
|
||||
|
||||
var total = capacity_val + disk_val;
|
||||
|
||||
if (total != 0 && Config.isFeatureEnabled("showback")) {
|
||||
$(".total_cost_div", context).show();
|
||||
|
||||
$(".total_cost_div .cost_value", context).text( (total).toFixed(2) );
|
||||
}
|
||||
}
|
||||
|
||||
function _calculateFlowCost(){
|
||||
var context = $("#provision_create_flow");
|
||||
|
||||
var total = 0;
|
||||
|
||||
$.each($(".provision_create_service_cost_div .cost_value", context), function(){
|
||||
total += parseFloat($(this).text());
|
||||
});
|
||||
|
||||
if (total != 0 && Config.isFeatureEnabled("showback")) {
|
||||
$(".total_cost_div", context).show();
|
||||
|
||||
$(".total_cost_div .cost_value", context).text( (total).toFixed(2) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function show_provision_dashboard() {
|
||||
$(".section_content").hide();
|
||||
$("#provision_dashboard").fadeIn();
|
||||
@ -568,7 +555,7 @@ define(function(require) {
|
||||
|
||||
$("#provision_create_vm li:not(.is-active) a[href='#provision_dd_template']").trigger("click")
|
||||
|
||||
|
||||
$("#provision_create_vm .total_cost_div").hide();
|
||||
$("#provision_create_vm .alert-box-error").hide();
|
||||
|
||||
$(".section_content").hide();
|
||||
@ -591,6 +578,7 @@ define(function(require) {
|
||||
|
||||
$("li:not(.is-active) a[href='#provision_dd_flow_template']", context).trigger("click")
|
||||
|
||||
$(".total_cost_div", context).hide();
|
||||
$(".alert-box-error", context).hide();
|
||||
|
||||
$(".section_content").hide();
|
||||
@ -897,7 +885,8 @@ define(function(require) {
|
||||
DisksResize.insert({
|
||||
template_json: template_json,
|
||||
disksContext: disksContext,
|
||||
force_persistent: $(this).prop('checked')
|
||||
force_persistent: $(this).prop('checked'),
|
||||
cost_callback: _calculateCost
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -925,6 +914,8 @@ define(function(require) {
|
||||
$(".provision_accordion_template .selected_template_logo").html('<i class="fa fa-file-text-o fa-lg"/> ');
|
||||
}
|
||||
|
||||
$("#provision_create_vm .total_cost_div").hide();
|
||||
|
||||
$(".provision_accordion_template a").first().trigger("click");
|
||||
|
||||
OpenNebula.Template.show({
|
||||
@ -945,7 +936,8 @@ define(function(require) {
|
||||
DisksResize.insert({
|
||||
template_json: template_json,
|
||||
disksContext: disksContext,
|
||||
force_persistent: $("input.instantiate_pers", create_vm_context).prop("checked")
|
||||
force_persistent: $("input.instantiate_pers", create_vm_context).prop("checked"),
|
||||
cost_callback: _calculateCost
|
||||
});
|
||||
} else {
|
||||
disksContext.html("");
|
||||
@ -1150,6 +1142,8 @@ define(function(require) {
|
||||
var data = $(this).data("opennebula");
|
||||
var body = data.DOCUMENT.TEMPLATE.BODY;
|
||||
|
||||
$("#provision_create_flow .total_cost_div").hide();
|
||||
|
||||
$(".provision_accordion_flow_template .selected_template").show();
|
||||
$(".provision_accordion_flow_template .select_template").hide();
|
||||
$(".provision_accordion_flow_template .selected_template_name").html(TemplateUtils.htmlEncode(data.DOCUMENT.NAME))
|
||||
|
@ -16,7 +16,13 @@
|
||||
<form id="provision_create_flow" class="section_content" hidden>
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<h4>{{tr "Create Service"}}</h4>
|
||||
<h4>
|
||||
{{tr "Create Service"}}
|
||||
<span class="total_cost_div" hidden>
|
||||
<small class="cost_value">0.00</small>
|
||||
<small>{{tr "COST"}} / {{tr "HOUR"}}</small>
|
||||
</span>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
@ -16,7 +16,13 @@
|
||||
<form id="provision_create_vm" class="section_content" hidden>
|
||||
<div class="row">
|
||||
<div class="large-12 columns">
|
||||
<h4>{{tr "Create Virtual Machine"}}</h4>
|
||||
<h4>
|
||||
{{tr "Create Virtual Machine"}}
|
||||
<span class="total_cost_div" hidden>
|
||||
<small class="cost_value">0.00</small>
|
||||
<small>{{tr "COST"}} / {{tr "HOUR"}}</small>
|
||||
</span>
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
@ -69,6 +69,7 @@ define(function(require) {
|
||||
FormPanel.prototype.submitWizard = _submitWizard;
|
||||
FormPanel.prototype.onShow = _onShow;
|
||||
FormPanel.prototype.setup = _setup;
|
||||
FormPanel.prototype.calculateCost = _calculateCost;
|
||||
|
||||
return FormPanel;
|
||||
|
||||
@ -100,12 +101,28 @@ define(function(require) {
|
||||
DisksResize.insert({
|
||||
template_json: template_json,
|
||||
disksContext: $(".disksContext" + template_json.VMTEMPLATE.ID, context),
|
||||
force_persistent: persistent
|
||||
force_persistent: persistent,
|
||||
cost_callback: that.calculateCost.bind(that)
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function _calculateCost(){
|
||||
$.each($(".template-row", this.formContext), function(){
|
||||
var capacity_val = parseFloat( $(".capacity_cost_div .cost_value", $(this)).text() );
|
||||
var disk_val = parseFloat( $(".provision_create_template_disk_cost_div .cost_value", $(this)).text() );
|
||||
|
||||
var total = capacity_val + disk_val;
|
||||
|
||||
if (total != 0 && Config.isFeatureEnabled("showback")) {
|
||||
$(".total_cost_div", $(this)).show();
|
||||
|
||||
$(".total_cost_div .cost_value", $(this)).text( (capacity_val + disk_val).toFixed(2) );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _submitWizard(context) {
|
||||
if (!this.selected_nodes || this.selected_nodes.length == 0) {
|
||||
Notifier.notifyError(Locale.tr("No template selected"));
|
||||
@ -194,7 +211,8 @@ define(function(require) {
|
||||
DisksResize.insert({
|
||||
template_json: template_json,
|
||||
disksContext: $(".disksContext" + template_json.VMTEMPLATE.ID, context),
|
||||
force_persistent: $("input.instantiate_pers", context).prop("checked")
|
||||
force_persistent: $("input.instantiate_pers", context).prop("checked"),
|
||||
cost_callback: that.calculateCost.bind(that)
|
||||
});
|
||||
|
||||
NicsSection.insert(template_json,
|
||||
@ -242,6 +260,8 @@ define(function(require) {
|
||||
}
|
||||
|
||||
$(".cost_value", capacityContext).html(cost.toFixed(2));
|
||||
|
||||
_calculateCost(context);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -14,32 +14,38 @@
|
||||
{{! limitations under the License. }}
|
||||
{{! -------------------------------------------------------------------------- }}
|
||||
|
||||
<h6>
|
||||
{{element.NAME}}
|
||||
</h6>
|
||||
<div class="row">
|
||||
<div class="medium-6 small-12 columns capacityContext{{element.ID}}">
|
||||
<fieldset>
|
||||
<legend>
|
||||
<i class="fa fa-laptop"></i> {{tr "Capacity"}}
|
||||
<span class="capacity_cost_div" hidden>
|
||||
<span class="cost_value">0.00</span>
|
||||
<small>{{tr "COST"}} / {{tr "HOUR"}}</small>
|
||||
</span>
|
||||
</legend>
|
||||
<div>
|
||||
{{{capacityInputsHTML}}}
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="template-row" element-id="{{element.ID}}">
|
||||
<h5>
|
||||
{{element.NAME}}
|
||||
<span class="total_cost_div" hidden>
|
||||
<small class="cost_value">0.00</small>
|
||||
<small>{{tr "COST"}} / {{tr "HOUR"}}</small>
|
||||
</span>
|
||||
</h5>
|
||||
<div class="row">
|
||||
<div class="medium-6 small-12 columns capacityContext{{element.ID}}">
|
||||
<fieldset>
|
||||
<legend>
|
||||
<i class="fa fa-laptop"></i> {{tr "Capacity"}}
|
||||
<span class="capacity_cost_div" hidden>
|
||||
<span class="cost_value">0.00</span>
|
||||
<small>{{tr "COST"}} / {{tr "HOUR"}}</small>
|
||||
</span>
|
||||
</legend>
|
||||
<div>
|
||||
{{{capacityInputsHTML}}}
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="medium-6 small-12 columns disksContext{{element.ID}}"></div>
|
||||
</div>
|
||||
<div class="medium-6 small-12 columns disksContext{{element.ID}}"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="medium-6 small-12 columns template_user_inputs{{element.ID}}"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="small-12 columns nicsContext{{element.ID}}">
|
||||
<div class="provision_network_selector">
|
||||
<div class="row">
|
||||
<div class="medium-6 small-12 columns template_user_inputs{{element.ID}}"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="small-12 columns nicsContext{{element.ID}}">
|
||||
<div class="provision_network_selector">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -28,7 +28,7 @@ define(function(require){
|
||||
'retrieve': _retrieve
|
||||
};
|
||||
|
||||
function _calculateCost(context, disk_cost){
|
||||
function _calculateCost(context, disk_cost, callback){
|
||||
var cost = 0;
|
||||
|
||||
$(".diskContainer", context).each(function(){
|
||||
@ -51,6 +51,10 @@ define(function(require){
|
||||
});
|
||||
|
||||
$(".cost_value", context).text(cost.toFixed(2));
|
||||
|
||||
if(callback != undefined){
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,6 +62,7 @@ define(function(require){
|
||||
* - disksContext: jquery selector, where to place the html
|
||||
* - force_persistent {bool}: mark all disks as if they
|
||||
* were persistent, disabling resize inputs
|
||||
* - cost_callback: function to call when the cost changes
|
||||
*/
|
||||
function _insert(opts) {
|
||||
|
||||
@ -80,14 +85,16 @@ define(function(require){
|
||||
disk_cost = Config.onedConf.DEFAULT_COST.DISK_COST;
|
||||
}
|
||||
|
||||
disksContext.off("input", "input");
|
||||
|
||||
if (disk_cost != 0 && Config.isFeatureEnabled("showback")) {
|
||||
$(".provision_create_template_disk_cost_div", disksContext).show();
|
||||
|
||||
disksContext.on("input", "input", function(){
|
||||
_calculateCost(disksContext, disk_cost);
|
||||
_calculateCost(disksContext, disk_cost, opts.cost_callback);
|
||||
});
|
||||
|
||||
_calculateCost(disksContext, disk_cost);
|
||||
_calculateCost(disksContext, disk_cost, opts.cost_callback);
|
||||
} else {
|
||||
$(".provision_create_template_disk_cost_div", disksContext).hide();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user