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

F #4132: Redesign Oneflow logic (#4389)

* Redesign Update & Instantiate Oneflow Template
* Change charter and group alias by nic
* Remove IP bower dependency
This commit is contained in:
Sergio Betanzos 2020-03-19 17:31:37 +01:00 committed by GitHub
parent 16ede88fd4
commit 2a7ba8457b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 403 additions and 417 deletions

View File

@ -22,9 +22,6 @@ require.config({
/* Almond */
"almond": "../bower_components/almond/almond",
/* IP */
"ip": "../bower_components/ip/src/ip",
/* BUFFER */
"buffer": "../bower_components/buffer/buffer.min",

View File

@ -664,6 +664,7 @@ define(function(require) {
return MIGRATE_ACTION_STR[stateId];
},
"ipsStr": ipsStr,
"groupByIpsStr": groupByIpsStr,
"aliasStr": aliasStr,
"retrieveExternalIPs": retrieveExternalIPs,
"retrieveExternalNetworkAttrs": retrieveExternalNetworkAttrs,
@ -754,7 +755,7 @@ define(function(require) {
// Return the IP or several IPs of a VM
function ipsStr(element, divider) {
var divider = divider || "<br>";
var nic = element.TEMPLATE.NIC;
var nics = element.TEMPLATE.NIC;
var pci = element.TEMPLATE.PCI;
var ips = [];
var monitoring = element.MONITORING;
@ -775,12 +776,12 @@ define(function(require) {
});
}
if (nic == undefined){
nic = [];
if (nics == undefined){
nics = [];
}
if (!$.isArray(nic)) {
nic = [nic];
if (!$.isArray(nics)) {
nics = [nics];
}
if (pci != undefined) {
@ -790,32 +791,45 @@ define(function(require) {
$.each(pci, function(){
if (this["TYPE"] == "NIC"){
nic.push(this);
nics.push(this);
}
});
}
if(ips.length==0)
{
$.each(nic, function(index, value) {
$.each(NIC_IP_ATTRS, function(j, attr){
if (value[attr]) {
if ( attr === "IP" && value["RDP"] === "YES") {
ips.push(value[attr] + "&nbsp;<small>RDP</small>");
} else {
// infoextended: alias will be group by nic
return (config.system_config.get_extended_vm_info)
? groupByIpsStr(element, nics)
: (ips.length == 0)
? $.each(nics, function(index, value) {
$.each(NIC_IP_ATTRS, function(j, attr){
if (value[attr] && attr === "IP") {
ips.push(value[attr]);
}
}
});
})
: (ips.length > 0) ? ips.join(divider) : r = "--";
};
function groupByIpsStr(element = {}, nics = []) {
return nics.reduce(function(column, nic) {
var nicSection = $("<p>").css("margin-bottom", 0).text(nic.IP)
if (nic.ALIAS_IDS) {
nicSection.append("*");
nic.ALIAS_IDS.split(",").forEach(function(aliasId) {
var alias = element.TEMPLATE.NIC_ALIAS.find(function(alias) { return alias.NIC_ID === aliasId })
if (alias) {
nicSection.append($("<p/>").css({
"margin-bottom": 0,
"font-style": "italic",
}).text(alias.IP)) }
});
});
}
r=null;
if (ips.length > 0) {
r = ips.join(divider);
} else {
r = "--";
}
return r;
}
return column.append(nicSection);
}, $("<div/>")).html()
};
// Return the Alias or several Aliases of a VM
@ -832,8 +846,7 @@ define(function(require) {
nic_alias = [nic_alias];
}
if(ips.length==0)
{
if(ips.length==0) {
$.each(nic_alias, function(index, value) {
$.each(NIC_ALIAS_IP_ATTRS, function(j, attr){
if (value[attr]) {

View File

@ -45,7 +45,21 @@ define(function(require) {
"ServiceTemplate.rename": _commonActions.singleAction("rename"),
"ServiceTemplate.update" : _commonActions.update(),
"ServiceTemplate.update_dialog" : _commonActions.checkAndShowUpdate(),
"ServiceTemplate.show_to_update" : _commonActions.showUpdate(CREATE_DIALOG_ID),
"ServiceTemplate.show_to_update" : {
type: "single",
call: OpenNebulaResource.show,
callback: function(request, response) {
Sunstone.runAction("Network.list")
Sunstone.runAction("VNTemplate.list")
Sunstone.showFormPanel(TAB_ID, CREATE_DIALOG_ID, "update",
function(formPanelInstance, context) {
formPanelInstance.fill(context, response[XML_ROOT]);
}
);
},
error: Notifier.onError
},
"ServiceTemplate.list" : {
type: "list",

View File

@ -22,13 +22,12 @@ define(function(require) {
// require('foundation.tab');
var BaseFormPanel = require('utils/form-panels/form-panel');
var Sunstone = require('sunstone');
var OpenNebulaAction = require("opennebula/action");
var Locale = require('utils/locale');
var Tips = require('utils/tips');
var RoleTab = require('tabs/oneflow-templates-tab/utils/role-tab');
var TemplateUtils = require('utils/template-utils');
var CustomTagsTable = require('utils/custom-tags-table');
var CustomClassCustomAttrs = 'service_custom_attr';
var CustomClassCustomAttrsButton = 'add_service_custom_attr';
var UserInputs = require('utils/user-inputs');
/*
TEMPLATES
@ -88,13 +87,7 @@ define(function(require) {
function _htmlWizard() {
return TemplateWizardHTML({
'formPanelId': this.formPanelId,
'customTagsTableHTML': CustomTagsTable.html(
CustomClassCustomAttrs,
CustomClassCustomAttrsButton,
true,
true, //mandatory
true, //default
)
'userInputsHTML': UserInputs.html(),
});
}
@ -105,30 +98,60 @@ define(function(require) {
}
function _setup(context) {
this.networksType = [
//Template id the una VN Template
{value: 'template_id', text: 'Create', select: 'vntemplates', extra: true },
//ID de una vnet que ya existe para reservar de ella
{value: 'reserve_from', text: 'Reserve', select: 'networks', extra: true },
//ID de una vnet que ya existe para usarla directamente
{value: 'id', text: 'Existing', select: 'networks', extra: false },
]
this.roleTabObjects = {};
var that = this;
var roles_index = 0;
$(".add_service_network", context).on("click", function(){
$(".add_service_network", context).bind("click", function() {
var nic_index = $(".service_network_name", context).length;
$(".service_networks tbody").append(
'<tr>\
'<tr id="network'+nic_index+'">\
<td>\
<input checked="" type="checkbox" name="service_network_mandatory'+nic_index+'"\
class="switch input service_network_mandatory slaac" id="service_network_mandatory'+nic_index+'" hidden="">\
<label class="switch-paddle" for="service_network_mandatory'+nic_index+'" style="cursor: pointer;"></label>\
</td>\
<td>\
<input class="service_network_name" type="text" />\
<small class="form-error"><br/>'+Locale.tr("Can only contain alphanumeric and underscore characters, and be unique")+'</small>\
</td>\
<td>\
<textarea class="service_network_description"/>\
<textarea class="service_network_description" />\
</td>\
<td>\
<select class="service_network_type">\
<option value=" "></option>\
</select>\
</td>\
<td>\
<select class="service_network_id">\
<option value=" "></option>\
</select>\
</td>\
<td>\
<input disabled class="service_network_extra" type="text" />\
</td>\
<td style="text-align: right;">\
<a href="#"><i class="fas fa-times-circle remove-tab" data-index="'+nic_index+'"></i></a>\
</td>\
</tr>');
that.networksType.map(function(type) {
$(".service_network_type", "tr#network"+nic_index).append($("<option/>", {
"value": type.value
}).text(type.text))
})
});
$(".add_service_network", context).trigger("click");
//$(".add_service_network", context).click();
context.on("keyup", ".service_network_name", function(){
// update pattern regex
@ -141,6 +164,31 @@ define(function(require) {
_redo_service_networks_selector(context, that);
});
context.on("change", ".service_network_type", function(){
var selectedType = $(this).val()
var serviceNetwork = $(this).closest('tr')
var data = _get_networks()
// 1. if val = reserve/existing or create
$(".service_network_id", serviceNetwork).empty().append($("<option/>").text(""))
// 2. create and fill selector
var type = that.networksType.find(function(type) { return type.value === selectedType })
// 3. append selector after type
type && data[type.select].map(function(net) {
$(".service_network_id", serviceNetwork).append($("<option/>", {
"value": net.ID
}).text(net.NAME))
})
// 4. append extra after selector if reserve/create
var disabled = type ? !type.extra : true;
!disabled && $(".service_network_extra", serviceNetwork).empty();
$(".service_network_extra", serviceNetwork).prop('disabled', disabled);
});
context.on("click", ".service_networks i.remove-tab", function(){
var tr = $(this).closest('tr');
tr.remove();
@ -148,11 +196,10 @@ define(function(require) {
_redo_service_networks_selector(context, that, $(this).data("index"));
});
that.roles_index = 0;
$("#tf_btn_roles", context).bind("click", function(){
that.addRoleTab(roles_index, context);
roles_index++;
return false;
that.addRoleTab(that.roles_index, context);
that.roles_index++;
});
// Fill parents table
@ -194,13 +241,12 @@ define(function(require) {
});
});
Foundation.reflow(context, 'tabs');
// Add first role
$("#tf_btn_roles", context).trigger("click");
$("#tf_btn_roles", context).click();
Tips.setup(context);
CustomTagsTable.setup(context, true);
UserInputs.setup(context);
return false;
}
@ -217,29 +263,28 @@ define(function(require) {
var network_attrs = {};
// get values for networks
var attr_type = "vnet_id";
var attr_network = "network";
$(".service_networks tbody > tr").each(function(){
var attr_name = $(".service_network_name", $(this)).val();
var row = $(this);
var attr_name = $(".service_network_name", row).val();
if (attr_name) {
var attr_desc = $(".service_network_description", $(this)).val() || '';
network_attrs[attr_name] = "M|" + attr_type + "|" + attr_desc;
var attr_mandatory = $(".service_network_mandatory", row).prop('checked') ? 'M' : 'O';
var attr_desc = ($(".service_network_description", row).val() || '');
var attr_type = $(".service_network_type", row).val() || '';
var attr_id = $(".service_network_id", row).val() || '';
var type = that.networksType.find(function(type) { return type.value === attr_type })
var attr_extra = type.extra ? (':' + ($(".service_network_extra", row).val() || '')) : '';
network_attrs[attr_name] = attr_mandatory + "|" + attr_network + "|" + attr_desc + "| |" + attr_type + ":" + attr_id + attr_extra;
}
});
// get values for custom attributes
$("."+CustomClassCustomAttrs+" tbody.custom_tags > tr").each(function(){
var row = $(this);
var attr_name = $(".custom_tag_key", row).val();
if (attr_name) {
var attr_type = $(".custom_tag_mandatory", row).val()? $(".custom_tag_mandatory", row).val() : 'M';
var attr_desc = $(".custom_tag_value", row).val()? "|"+$(".custom_tag_value", row).val() : '';
var attr_default = $(".custom_tag_default", row).val()? "|"+$(".custom_tag_default", row).val() : '';
custom_attrs[attr_name] = attr_type + attr_desc + attr_default;
}
var userInputsJSON = UserInputs.retrieve(context);
$.each(userInputsJSON, function(key, value){
var name = key.toUpperCase();
custom_attrs[name] = value
});
var roles = [];
$('.role_content', context).each(function() {
var role_id = $(this).attr("role_id");
@ -329,59 +374,45 @@ define(function(require) {
$("select[name='shutdown_action_service']", context).val(element.TEMPLATE.BODY.shutdown_action);
$("input[name='ready_status_gate']", context).prop("checked",element.TEMPLATE.BODY.ready_status_gate || false);
$(".service_networks i.remove-tab", context).trigger("click");
//fill form networks
if ( ! $.isEmptyObject( element.TEMPLATE.BODY['networks'] ) ) {
$("div#network_configuration a.accordion_advanced_toggle", context).trigger("click");
$.each(element.TEMPLATE.BODY['networks'], function(key, attr){
// 0 mandatory; 1 network; 2 description; 3 empty; 4 info_network;
var parts = attr.split("|");
// 0 mandatory; 1 type; 2 desc;
// 0 type; 1 id; 3(optional) extra
var info = parts.slice(-1)[0].split(":");
var attrs = {
"name": key,
"mandatory": parts[0],
"type": parts[1],
"mandatory": parts[0] === 'M' ? true : false,
"network": parts[1],
"description": parts[2],
"empty": parts[3],
"type": info[0],
"id": info[1],
"extra": info.slice(2).join(''),
};
switch (parts[1]) {
case "vnet_id":
$(".add_service_network", context).trigger("click");
var tr = $(".service_networks tbody > tr", context).last();
$(".service_network_name", tr).val(attrs.name).change();
$(".service_network_description", tr).val(attrs.description);
break;
if (parts[1] === "network") {
$(".add_service_network", context).trigger("click");
var tr = $(".service_networks tbody > tr", context).last();
$(".service_network_mandatory", tr).prop('checked', attrs.mandatory).change();
$(".service_network_name", tr).val(attrs.name).change();
$(".service_network_description", tr).val(attrs.description).change();
$(".service_network_type", tr).val(attrs.type).change();
$(".service_network_id", tr).val(attrs.id).change();
$(".service_network_extra", tr).val(attrs.extra).change();
}
});
}
//fill form custom attributes
if ( ! $.isEmptyObject( element.TEMPLATE.BODY['custom_attrs'] ) ) {
var custom_attrs = element.TEMPLATE.BODY['custom_attrs']
if (! $.isEmptyObject(custom_attrs)) {
$("div#custom_attr_values a.accordion_advanced_toggle", context).trigger("click");
$.each(element.TEMPLATE.BODY['custom_attrs'], function(key, attr){
var parts = attr.split("|");
// 0 mandatory; 1 desc;
var attrs = {
"name": key,
"mandatory": parts[0],
"description": parts[1],
'default': parts[2]
};
var tr = $("."+CustomClassCustomAttrs+" tbody.custom_tags > tr", context).last();
if($(".custom_tag_key", tr).val()){
$("."+CustomClassCustomAttrsButton, context).trigger("click");
tr = $("."+CustomClassCustomAttrs+" tbody.custom_tags > tr", context).last();
}
$(".custom_tag_key", tr).val(attrs.name);
if(attrs.mandatory){
var select = $(".custom_tag_mandatory", tr);
select.find("option").removeAttr("selected");
var selected = select.find("option[value="+attrs.mandatory+"]").attr("selected","selected");
}
$(".custom_tag_value", tr).val(attrs.description);
$(".custom_tag_default", tr).val(attrs.default);
});
UserInputs.fill(context, {"USER_INPUTS": custom_attrs});
}
$("#roles_tabs i.remove-tab", context).trigger("click");
@ -533,4 +564,34 @@ define(function(require) {
role_tab.onShow();
}
function _get_networks() {
var networks = OpenNebulaAction.cache("VNET");
networks = networks ? networks.data : [];
var vntemplates = OpenNebulaAction.cache("VNTEMPLATE");
vntemplates = vntemplates ? vntemplates.data : [];
// Get networks list
if (networks) {
var data = Array.isArray(networks) ? networks : [];
networks = data.map(function(net) {
return ({
ID: net.VNET.ID,
NAME: net.VNET.NAME || "vnet-"+net.VNET.ID
})
})
}
// Get network templates list
if (vntemplates) {
var data = Array.isArray(vntemplates) ? vntemplates : [];
vntemplates = data.map(function(temp) {
return ({
ID: temp.VNTEMPLATE.ID,
NAME: temp.VNTEMPLATE.NAME || "vntemplate-"+template.VNTEMPLATE.ID
})
})
}
return ({ networks: networks, vntemplates: vntemplates })
}
});

View File

@ -41,16 +41,20 @@
<table class="service_networks policies_table dataTable">
<thead>
<tr>
<th style="width:30%">{{tr "Name"}}</th>
<th style="width:70%">{{tr "Description"}}</th>
<th style="width:3%"></th>
<th width="5%">{{tr "Mandatory"}}</th>
<th width="22%">{{tr "Name"}}</th>
<th width="23%">{{tr "Description"}}</th>
<th width="10%">{{tr "Type"}}</th>
<th id="service_network_id_label" width="15%">{{tr "Network"}}</th>
<th width="20%">{{tr "Extra"}}</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td colspan="3">
<td colspan="6">
<a type="button" class="add_service_network button small small-12 secondary radius"><i class="fas fa-lg fa-plus-circle"></i> {{tr "Network"}}</a>
</td>
</tr>
@ -62,7 +66,7 @@
</div>
<div id="custom_attr_values">
{{#advancedSection (tr "Custom Attributes Values Configuration") }}
{{{customTagsTableHTML}}}
{{{userInputsHTML}}}
{{/advancedSection}}
</div>
{{#advancedSection (tr "Advanced service parameters") }}

View File

@ -206,45 +206,35 @@ define(function(require) {
if (n_times_int > 1) {
extra_msg = n_times_int+" times";
}
var extra_info = {
"merge_template": {}
};
var networks_json = WizardFields.retrieve($(".network_attrs_class", context));
var custom_attrs_json = WizardFields.retrieve($(".custom_attr_class", context));
var network_values = [];
var prefix = "type_";
var networks = Object.keys(networks_json).filter(function(k) {
return k.indexOf('type_') == 0;
}).reduce(function(newData, k) {
var key = "id";
switch (networks_json[k]) {
case "create":
key = "template_id";
break;
case "reserve":
key = "reserve_from";
break;
default:
break;
}
var internal = {};
internal[k.replace(prefix,"")] = {};
internal[k.replace(prefix,"")][key] = networks_json[k.replace(prefix,"")];
if(networks_json[k] === "create" || networks_json[k] === "reserve"){
internal[k.replace(prefix,"")].extra = networks_json["extra_"+k.replace(prefix,"")];
}
newData[k.replace(prefix,"")] = internal;
var custom_attrs_json = WizardFields.retrieve($(".custom_attr_class", context));
var networks_json = WizardFields.retrieve($(".network_attrs_class", context));
var typePrefix = "type_";
var network_values = Object.keys(networks_json).filter(function(key) {
return key.indexOf(typePrefix) == 0; // get all networks names with prefix 'type_'
}).reduce(function(newData, typeKey) {
var type = networks_json[typeKey];
var name = typeKey.replace(typePrefix, '');
var id = networks_json[name]
var extra = networks_json['extra_' + name];
newData.push($.extend(true, {},{
[name]: {
[type]: id, // type configuration: id network/template
extra: (extra && extra !== "") ? extra : undefined,
},
}));
return newData;
}, {});
//parse to array
Object.keys(networks).map(function(key_network){
network_values.push(networks[key_network]);
});
}, []);
var extra_info = { "merge_template": {
custom_attrs_values: custom_attrs_json,
networks_values: network_values,
roles: []
}};
extra_info.merge_template.custom_attrs_values = custom_attrs_json;
extra_info.merge_template.networks_values = network_values;
extra_info.merge_template.roles = [];
$.each(that.service_template_json.DOCUMENT.TEMPLATE.BODY.roles, function(index, role){
var div_id = "user_input_role_"+index;
var tmp_json = {};

View File

@ -230,8 +230,7 @@ define(function(require) {
function _fill(context, value, network_names) {
var that = this;
$("#role_name", context).val(value.name);
$("#role_name", context).change();
$("#role_name", context).val(value.name).keyup();
$("#cardinality", context).val(value.cardinality);

View File

@ -22,7 +22,7 @@
<small class="form-error">{{tr "Can only contain alphanumeric and underscore characters"}}</small>
</label>
</div>
<div class="service_template_param service_role medium-2 columns end">
<div class="service_template_param service_role medium-4 columns end">
<label>
{{tr "Number of VMs"}}
<input type="number" min="0" id="cardinality" name="cardinality" value="1"/>
@ -39,37 +39,46 @@
</div>
</div>
<div class="row">
<div class="service_template_param service_role medium-6 columns">
<table class="networks_role dataTable">
<thead>
<tr>
<th colspan="2">
<i class="fas fa-lg fa-fw fa-globe off-color"/>{{tr "Network Interfaces"}}
</th>
</tr>
</thead>
<tbody class="networks_role_body">
</tbody>
</table>
<div class="form-group networks_role_rdp">
<label for="rdp">RDP</label>
<select class="form-control" id="rdp">
<option value=""></option>
</select>
<div class="large-12 columns networks_accordion">
{{#advancedSection (tr "Role network") }}
<div class="row">
<div class="service_template_param service_role medium-6 columns">
<table class="networks_role dataTable">
<thead>
<tr>
<th colspan="2">
<label for="interfaces_role">
<i class="fas fa-lg fa-fw fa-globe off-color"/>{{tr "Network Interfaces"}}
<span class="tip">{{tr "This network interface will be configured as an ALIAS in the VM without context configuration."}}</span>
</label>
</th>
</tr>
</thead>
<tbody class="networks_role_body">
</tbody>
</table>
<div class="form-group networks_role_rdp">
<label for="rdp">RDP</label>
<select class="form-control" id="rdp">
<option value=""></option>
</select>
</div>
</div>
<div class="service_template_param service_role medium-6 columns">
<table class="parent_roles dataTable">
<thead>
<tr>
<th colspan="2">
{{tr "Parent roles"}}
</th>
</tr>
</thead>
<tbody class="parent_roles_body">
</tbody>
</table>
</div>
</div>
</div>
<div class="service_template_param service_role medium-6 columns">
<table class="parent_roles dataTable">
<thead>
<tr>
<th colspan="2">
{{tr "Parent roles"}}
</th>
</tr>
</thead>
<tbody class="parent_roles_body">
</tbody>
</table>
{{/advancedSection}}
</div>
</div>
<br>

View File

@ -28,6 +28,7 @@ define(function(require) {
var Humanize = require("utils/humanize");
var TemplateUtils = require("utils/template-utils");
var Actions = require("utils/actions");
var Leases = require("utils/leases");
var TemplateHTML = require("hbs!./actions/html");
/*
@ -61,11 +62,12 @@ define(function(require) {
function _html() {
return TemplateHTML({
"table_sched_actions": ScheduleActions.htmlTable("temp")
"table_sched_actions": ScheduleActions.htmlTable("temp", Leases.html()),
});
}
function _onShow(context, panelForm) {
Leases.actions(panelForm);
}
function _setup(context) {

View File

@ -30,7 +30,6 @@ define(function(require) {
var UsersTable = require("tabs/users-tab/datatable");
var GroupTable = require("tabs/groups-tab/datatable");
var OpenNebulaHost = require("opennebula/host");
var Leases = require("utils/leases");
/*
TEMPLATES
@ -91,7 +90,6 @@ define(function(require) {
'logos': Config.vmLogos,
'usersDatatable': this.usersTable.dataTableHTML,
'groupDatatable': this.groupTable.dataTableHTML,
'leases': Leases.html()
});
}
@ -108,8 +106,6 @@ define(function(require) {
.prop('wizard_field_disabled', true);
}
Leases.actions(panelForm);
if (panelForm.resource == "VirtualRouterTemplate"){
$("input[wizard_field=VROUTER]", context).attr("checked", "checked");
}

View File

@ -90,18 +90,17 @@ define(function(require) {
function _html() {
return TemplateHTML({
"formPanelId": this.formPanelId,
"leases": Leases.html()
"formPanelId": this.formPanelId
});
}
function _setup(context) {
var that = this;
var leasesThat = {};
var objLeases = Object.assign(leasesThat, that);
var objLeases = $.extend(true, {}, that);
objLeases.resource = "template";
objLeases.__proto__ = FormPanel.prototype;
Leases.actions(objLeases);
if(Config.isFeatureEnabled("instantiate_persistent")){
$("input.instantiate_pers", context).on("change", function(){
var persistent = $(this).prop("checked");
@ -126,6 +125,7 @@ define(function(require) {
$("#vm_n_times_disabled", context).hide();
$("#vm_n_times", context).show();
}
context.off("click", "#add_scheduling_inst_action");
context.on("click", "#add_scheduling_inst_action", function() {
var actions = ["terminate", "terminate-hard", "hold", "release", "stop", "suspend", "resume", "reboot", "reboot-hard", "poweroff", "poweroff-hard", "undeploy", "undeploy-hard", "snapshot-create"];
@ -134,8 +134,9 @@ define(function(require) {
ScheduleActions.setup(context);
return false;
});
context.off("click", "#add_inst_action_json");
context.on("click" , "#add_inst_action_json", function(){
context.on("click", "#add_inst_action_json", function(){
var sched_action = ScheduleActions.retrieveNewAction(context);
if (sched_action != false) {
$("#sched_inst_actions_body").append(ScheduleActions.fromJSONtoActionsTable(sched_action));
@ -143,10 +144,12 @@ define(function(require) {
return false;
});
context.on("focusout" , "#time_input", function(){
$("#time_input").removeAttr("data-invalid");
$("#time_input").removeAttr("class");
});
context.off("click", ".remove_action_x");
context.on("click", ".remove_action_x", function(){
$(this).parents("tr").remove();
@ -413,7 +416,7 @@ define(function(require) {
dsDatatable: that.datastoresTable.dataTableHTML,
usersDatatable: that.usersTable.dataTableHTML,
groupDatatable: that.groupTable.dataTableHTML,
table_sched_actions: ScheduleActions.htmlTable("inst")
table_sched_actions: ScheduleActions.htmlTable("inst", Leases.html())
}) );
$(".provision_host_selector" + template_json.VMTEMPLATE.ID, context).data("hostsTable", that.hostsTable);
@ -599,9 +602,8 @@ define(function(require) {
function _onShow(context) {
Sunstone.disableFormPanelSubmit(this.tabId);
$("input.instantiate_pers", context).change();
var templatesContext = $(".list_of_templates", context);
templatesContext.html("");
Tips.setup(context);
return false;
}

View File

@ -36,9 +36,6 @@
</div>
</div>
<div class="row nameContainer">
<div class="medium-12 columns text-center">
{{{leases}}}
</div>
<div class="medium-4 columns">
<label for="vm_name">
{{tr "VM name"}}

View File

@ -24,7 +24,6 @@ define(function(require) {
var Vnc = require('utils/vnc');
var Spice = require('utils/spice');
var Rdp = require('utils/rdp');
var mapips = require('./utils/mapips');
var TAB_ID = require('./tabId');
var CREATE_DIALOG_ID = require('./form-panels/create/formPanelId');
@ -191,11 +190,6 @@ define(function(require) {
(propUpperCase === "USERNAME" || propUpperCase === "PASSWORD")
&& (credentials[propUpperCase] = context[prop]);
}
var pblc = vm.TEMPLATE.CONTEXT.MAP_EXTERNAL;
var prvt = vm.TEMPLATE.CONTEXT.MAP_INTERNAL;
var mapp = new mapips(pblc, prvt);
var foundip = mapp.renderPublicIp(ip);
ip = foundip || ip
}
nic && Rdp.downloadFile(ip, name, credentials);

View File

@ -19,12 +19,14 @@ define(function(require) {
DEPENDENCIES
*/
var Locale = require("utils/locale");
var Sunstone = require("sunstone");
var Humanize = require("utils/humanize");
var TemplateUtils = require("utils/template-utils");
var Config = require("sunstone-config");
var ScheduleActions = require("utils/schedule_action");
var Leases = require("utils/leases");
/*
CONSTANTS
@ -75,6 +77,7 @@ define(function(require) {
<th>" + Locale.tr("Message") + "</th>\
<th colspan=\"\"> </th>\
<th><button id=\"add_scheduling_vms_action\" class=\"button small success right radius\" >" + Locale.tr("Add action") + "</button></th>\
<th>" + Leases.html() + "</th>\
</tr>\
</thead>\
<tbody id=\"sched_vms_actions_body\">"+
@ -90,17 +93,23 @@ define(function(require) {
function _setup(context) {
var that = this;
var actions = ["terminate", "terminate-hard", "hold", "release", "stop", "suspend", "resume", "reboot", "reboot-hard", "poweroff", "poweroff-hard", "undeploy", "undeploy-hard", "snapshot-create"];
context.off("click", "#add_scheduling_vms_action");
context.on("click", "#add_scheduling_vms_action", function() {
$("#add_scheduling_vms_action", context).attr("disabled", "disabled");
that.formContext = context;
Leases.actions(that,'vm','update');
var actions = [
"terminate", "terminate-hard", "hold", "release", "stop", "suspend", "resume",
"reboot", "reboot-hard", "poweroff", "poweroff-hard", "undeploy", "undeploy-hard",
"snapshot-create"
];
$("#add_scheduling_vms_action").bind("click", context, function() {
$(this).attr("disabled", "disabled");
ScheduleActions.htmlNewAction(actions, context, "vms");
ScheduleActions.setup(context);
return false;
});
context.off("click", "#add_vms_action_json");
context.on("click" , "#add_vms_action_json", function(){
$("#add_vms_action_json").bind("click", context, function(){
var sched_action = ScheduleActions.retrieveNewAction(context);
if (sched_action != false) {
$("#no_actions_tr", context).remove();
@ -120,8 +129,7 @@ define(function(require) {
});
// Listener for key,value pair remove action
context.off("click", ".remove_action_x");
context.on("click", ".remove_action_x", function() {
$(".remove_action_x").bind("click", context, function() {
var index = this.id.substring(6, this.id.length);
var tmp_tmpl = new Array();
@ -136,7 +144,6 @@ define(function(require) {
// Let OpenNebula know
Sunstone.runAction("VM.update_template", that.element.ID, template_str);
});
}
// Returns an HTML string with the json keys and values

View File

@ -20,15 +20,12 @@ define(function(require) {
*/
var Locale = require("utils/locale");
var Leases = require("utils/leases");
var Humanize = require("utils/humanize");
var RenameTr = require("utils/panel/rename-tr");
var PermissionsTable = require("utils/panel/permissions-table");
var TemplateTable = require("utils/panel/template-table");
var TemplateTableVcenter = require("utils/panel/template-table");
var OpenNebula = require("opennebula");
var Sunstone = require("sunstone");
var Config = require("sunstone-config");
var Navigation = require("utils/navigation");
/*
@ -79,7 +76,8 @@ define(function(require) {
var IP = OpenNebula.VM.ipsStr(this.element);
var alias = OpenNebula.VM.aliasStr(this.element);
var alias = (!config.system_config.get_extended_vm_info)
? OpenNebula.VM.aliasStr(this.element) : null;
if (this.element.TEMPLATE.VROUTER_ID != undefined){
vrouterHTML = Navigation.link(
@ -141,7 +139,6 @@ define(function(require) {
"templateTableHTML": templateTableHTML,
"monitoringTableContentHTML": monitoringTableContentHTML,
"vrouterHTML": vrouterHTML,
"leases": Leases.html()
});
}
@ -167,7 +164,6 @@ define(function(require) {
if($.isEmptyObject(strippedTemplateVcenter)){
$(".vcenter", context).hide();
}
Leases.actions(that,'vm','update');
TemplateTable.setup(strippedTemplate, RESOURCE, this.element.ID, context, unshownValues, strippedTemplateVcenter);
TemplateTableVcenter.setup(strippedTemplateVcenter, RESOURCE, this.element.ID, context, unshownValues, strippedTemplate);
}

View File

@ -15,9 +15,6 @@
{{! -------------------------------------------------------------------------- }}
<div class="row">
<div class="medium-12 columns text-center">
{{{leases}}}
</div>
<div class="large-6 columns">
<table class="dataTable">
<thead>
@ -56,11 +53,13 @@
<td></td>
</tr>
<tr>
<td class="key_td">{{tr "Alias"}}</td>
<td class="value_td">{{{alias}}}</td>
<td></td>
</tr>
{{#if alias }}
<tr>
<td class="key_td">{{tr "Alias"}}</td>
<td class="value_td">{{{alias}}}</td>
<td></td>
</tr>
{{/if }}
<tr>
<td class="key_td">{{tr "Start time"}}</td>

View File

@ -22,7 +22,6 @@ define(function(require) {
var TemplateUtils = require('utils/template-utils');
var LabelsUtils = require('utils/labels/utils');
var Status = require('utils/status');
var mapips = require('./mapips');
var RESOURCE = "VM";
var XML_ROOT = "VM";
@ -96,70 +95,6 @@ define(function(require) {
return rtn;
}
function renderMapIps(element){
var render = '';
if(
element &&
element.NAME &&
element.TEMPLATE &&
element.TEMPLATE.CONTEXT &&
element.TEMPLATE.CONTEXT.MAP_EXTERNAL &&
element.TEMPLATE.CONTEXT.MAP_INTERNAL &&
element.TEMPLATE.NIC &&
config &&
config.system_config &&
config.system_config.get_extended_vm_info &&
config.system_config.get_extended_vm_info !== 'false' &&
config.system_config.mapped_ips &&
config.system_config.mapped_ips !== 'false'
){
var nics = element.TEMPLATE.NIC;
var credentials = {};
var context = element.TEMPLATE.CONTEXT;
var pblc = element.TEMPLATE.CONTEXT.MAP_EXTERNAL; //"10.0.0.0/8";
var prvt = element.TEMPLATE.CONTEXT.MAP_INTERNAL; //"192.168.0.0/16";
var renderTitle = true;
if (!$.isArray(nics)){
nics = [nics];
}
//find RDP CREDENTIALS
for (var prop in context) {
var propUpperCase = String(prop).toUpperCase();
(propUpperCase === "USERNAME" || propUpperCase === "PASSWORD")
&& (credentials[propUpperCase] = context[prop]);
}
var mapp = new mapips(pblc, prvt);
nics.forEach(function(nic){
if(nic && nic.IP){
var foundip = mapp.renderPublicIp(nic.IP);
if (foundip){
if(renderTitle){
render = $('<div/>').append($('<br/>').add($('<b/>').text(Locale.tr('Mapped Networks')))).html();
renderTitle = false;
}
if(nic.RDP && String(nic.RDP).toUpperCase() === "YES"){
render += $("<div/>").append(
$("<button/>",{
class:'button download_rdp',
ip: foundip,
name:element.NAME,
credential: TemplateUtils.templateToString(credentials)
}).css({display:'block'}).text("RDP: "+foundip)
).html();
}else{
render += $("<div/>").append(
$("<div/>").text(foundip)
).html();
}
}
}
});
}
return render;
}
function leasesClock(element){
var rtn = "";
if(
@ -295,7 +230,7 @@ define(function(require) {
cpuMonitoring,
Humanize.size(memoryMonitoring),
hostname,
OpenNebulaVM.ipsStr(element)+renderMapIps(element),
OpenNebulaVM.ipsStr(element),
Humanize.prettyTimeDatatable(element.STIME),
vncIcon,
TemplateUtils.htmlEncode(TemplateUtils.templateToString(element)),

View File

@ -1,85 +0,0 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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. */
/* -------------------------------------------------------------------------- */
define(function(require) {
var ip = require('ip');
// var publicIp = "10.10.0.0/24";
// var privateIp = "192.168.10.0/24";
// var x = "192.168.10.1";
class mapips {
constructor(pblc, prvt) {
this.pblc = pblc || "";
this.prvt = prvt || "";
this.rtn = "";
}
intToip(ipInt) {
return (
(ipInt >>> 24) +
"." +
((ipInt >> 16) & 255) +
"." +
((ipInt >> 8) & 255) +
"." +
(ipInt & 255)
);
}
ipToint(ip) {
return (
ip.split(".").reduce(function(ipInt, octet) {
return (ipInt << 8) + parseInt(octet, 10);
}, 0) >>> 0
);
}
mapIPprivate(ipnic) {
var dataPublic = this.pblc.split("/");
var dataPrivate = this.prvt.split("/");
var nic = ipnic || "";
if (
Array.isArray(dataPrivate) &&
Array.isArray(dataPublic) &&
dataPublic[0] &&
dataPublic[1] &&
dataPrivate[0] &&
dataPrivate[1]
) {
var mask = ip.fromPrefixLen(dataPublic[1]);
var networkPublic = ip.mask(dataPublic[0], mask);
mask = ip.fromPrefixLen(dataPrivate[1]);
var hostBytes = ip.not(mask);
var hostsPrivate = ip.mask(ipnic, hostBytes);
this.rtn = this.intToip(
this.ipToint(networkPublic) + this.ipToint(hostsPrivate)
);
}
return this.rtn;
}
renderPublicIp(nic) {
var ipnic = nic || "";
var rtn = '';
if (ip.cidrSubnet(this.prvt).contains(ipnic)) {
rtn = this.mapIPprivate(ipnic);
}
return rtn;
}
}
// var mapp = new Mapips(publicIp, privateIp);
// console.log("->", mapp.renderPublicIp(x));
return mapips;
});

View File

@ -29,7 +29,7 @@ define(function(require) {
CONSTANTS
*/
var classButton = 'button leases';
var classButton = 'small button leases right radius';
var idElementSchedActions = '#sched_temp_actions_body, #sched_inst_actions_body';
/*
@ -72,7 +72,8 @@ define(function(require) {
config.system_config &&
config.system_config.leases
){
$(parseVarToJqueryClass(classButton)).off("click").on("click", function(e){
form.formContext.off("click", parseVarToJqueryClass(classButton))
form.formContext.on("click", parseVarToJqueryClass(classButton), function(e){
e.preventDefault();
var confLeases = config.system_config.leases;
var confLeasesKeys = Object.keys(confLeases);

View File

@ -25,10 +25,11 @@ define(function (require) {
var TemplateHTML = require("hbs!./schedule_action/html");
var TemplateTableHTML = require("hbs!./schedule_action/table");
function _html(resource) {
function _html(resource, leases = null) {
this.res = resource;
return TemplateTableHTML({
res: resource
res: resource,
leases: leases
});
}

View File

@ -32,6 +32,7 @@
<th>
<button id="add_scheduling_{{res}}_action" class="button small success right radius"> {{tr "Add action"}} </button>
</th>
{{#if leases}} <th>{{{leases}}}</th> {{/if}}
</tr>
</thead>
<tbody id="sched_{{res}}_actions_body"></tbody>

View File

@ -61,7 +61,7 @@ define(function(require) {
}
function _setup(context){
context.on("click", ".add_user_input_attr", function() {
$(".add_user_input_attr", context).bind("click", function() {
$(".user_input_attrs tbody", context).append(RowTemplateHTML({"idInput": UniqueId.id()}));
$("tbody label").css("cursor", "pointer");
$("select.user_input_type", context).change();
@ -113,6 +113,8 @@ define(function(require) {
attr.description = $(".user_input_description", $(this)).val();
switch(attr.type){
case "text":
case "text64":
case "number":
case "number-float":
case "fixed":
@ -181,6 +183,8 @@ define(function(require) {
}
switch(attr.type){
case "text":
case "text64":
case "number":
case "number-float":
case "fixed":
@ -326,25 +330,31 @@ define(function(require) {
return rtn;
}
function addInVar(iterator, store, index, notype){
function addInVar(iterator, store){
if(iterator && store && Array.isArray(store)){
$.each(iterator, function(key, value) {
var attrs = _parse(key, value, notype);
var attrs = _parse(key, value);
if (defaults[key] != undefined){
attrs.initial = opts.defaults[key];
}
if(checkItemInArray(attrs, store, 'name')){
store.push(attrs);
if(index){
check[index]=true;
}
}
});
}
}
addInVar(networks, network_attrs);
addInVar(customs, custom_attrs, 'customs', true); //4 params remove the type
addInVar(customs, custom_attrs);
this.networksType = [
//Template id the una VN Template
{value: 'template_id', text: 'Create', select: 'vntemplates', extra: true },
//ID de una vnet que ya existe para reservar de ella
{value: 'reserve_from', text: 'Reserve', select: 'networks', extra: true },
//ID de una vnet que ya existe para usarla directamente
{value: 'id', text: 'Existing', select: 'networks', extra: false },
]
// Render networks
if (network_attrs.length > 0) {
@ -358,14 +368,25 @@ define(function(require) {
html = "";
var separator = $("<div>");
$.each(network_attrs, function(index, vnet_attr) {
// 0 type; 1 id; 3(optional) extra
var info = vnet_attr.initial.split(":")
var type = info[0];
var id = info[1];
var extra = info.slice(2).join('');
var unique_id = "vnet_user_input_" + UniqueId.id();
vnetsTable = new VNetsTable(unique_id, {"select": true});
if(type === "reserve_from" || type === "id") {
var table = new VNetsTable(unique_id, {"select": true});
}else {
var table = new VNetsTemplateTable(unique_id, {"select": true});
}
if(opts && opts.select_networks){
$("."+network_attrs_class, div).append(
$("<div>", {class:"row"}).append(
$("<div>",{class: "large-12 large-centered columns"}).append(
separator.add(
$("<h5>").text(TemplateUtils.htmlEncode(vnet_attr.name)).add(
$("<h6>").text(TemplateUtils.htmlEncode(vnet_attr.name)).add(
$("<div>",{class: "row"}).append(
$("<div>",{class:"columns small-12"}).append(
$("<select>",{
@ -375,18 +396,21 @@ define(function(require) {
'data-idtable': unique_id,
'data-id': index
}).append(
$("<option>",{value:"existing"}).text(Locale.tr("Existing")).add(
$("<option>", {value: "create"}).text(Locale.tr("Create"))
$("<option>",{ value: "id" }).text(Locale.tr("Existing")
).add(
$("<option>", {value: "reserve"}).text(Locale.tr("Reserve"))
$("<option>", {value: "template_id"}).text(Locale.tr("Create"))
).add(
$("<option>", {value: "reserve_from"}).text(Locale.tr("Reserve"))
)
)
).add($("<div>",
{
class:"columns small-12",
id:"placeDatatable_"+index
}
).html(vnetsTable.dataTableHTML))
).add(
$("<div>",
{
class:"columns small-12",
id:"placeDatatable_"+index
}
).html(table.dataTableHTML)
)
)
)
)
@ -395,9 +419,30 @@ define(function(require) {
);
}
separator = $("<hr/>");
vnetsTable.initialize();
table.initialize();
$("#refresh_button_" + unique_id).click();
vnetsTable.idInput().attr("wizard_field", vnet_attr.name).attr("required", "");
table.idInput().attr("wizard_field", vnet_attr.name).attr("required", "");
// Fill type, id of vnet/vnet-template and extra
$(".changePlaceDatatable[data-id="+index+"]").val(type)
table.selectResourceTableSelect({ 'ids': String(id) })
if (type === "template_id" || type === "reserve_from") {
$("#placeDatatable_"+index).append(
$("<div/>",{'class': "row addExtra_"+id}).append(
$("<div/>",{'class': "columns small-12"}).append(
$("<label/>").text(Locale.tr("Extra")).add(
$("<input/>",{
'wizard_field': "extra_"+vnet_attr.name,
'type': "text",
'name': "extra",
'id': "extra",
'placeholder': Locale.tr("Extra")
}).val(extra)
)
)
)
)
}
});
if(opts && opts.select_networks){
$(".changePlaceDatatable").change(function(e){
@ -408,21 +453,18 @@ define(function(require) {
var nametable = element.attr("data-nametable");
var value = element.val();
var place = $("#placeDatatable_"+id);
if(value === "reserve" || value === "existing"){
var vnetsTable = new VNetsTable(idtable, {"select": true});
place.empty().append(vnetsTable.dataTableHTML);
vnetsTable.initialize();
$("#refresh_button_"+idtable).click();
vnetsTable.idInput().attr("wizard_field", nametable).attr("required", "");
if(value === "reserve_from" || value === "id"){
var table = new VNetsTable(idtable, {"select": true});
}else{
var vnetsTemplateTable = new VNetsTemplateTable(idtable, {"select": true});
place.empty().append(vnetsTemplateTable.dataTableHTML);
vnetsTemplateTable.initialize();
$("#refresh_button_"+idtable).click();
vnetsTemplateTable.idInput().attr("wizard_field", nametable).attr("required", "");
var table = new VNetsTemplateTable(idtable, {"select": true});
}
place.empty().append(table.dataTableHTML);
table.initialize();
$("#refresh_button_"+idtable).click();
table.idInput().attr("wizard_field", nametable).attr("required", "");
// create input extra
if(value === "create" || value === "reserve"){
if(value === "template_id" || value === "reserve_from"){
// falta colocar el render de las diferentes tablas!!!
if(!place.find(".addExtra_"+id).length){
place.append(
@ -520,6 +562,8 @@ define(function(require) {
(attr.type != undefined ? attr.type : "text") + "|" +
(attr.description != undefined ? attr.description : "");
switch (attr.type) {
case "text":
case "text64":
case "number":
case "number-float":
case "boolean":
@ -548,12 +592,12 @@ define(function(require) {
* ["initial":] "3"
* }
*/
function _unmarshall(value, notype) {
function _unmarshall(value) {
var parts = value.split("|");
var attr = {
"mandatory": (parts[0] == "M"),
"type": notype? parts[2]: parts[1],
"description": notype? parts[1] : parts[2],
"type": parts[1],
"description": parts[2],
"initial": ""
};
if (parts[3] != undefined){
@ -584,8 +628,8 @@ define(function(require) {
starting from 0, not min
}
*/
function _parse(name, value, notype) {
var attr = _unmarshall(value, notype);
function _parse(name, value) {
var attr = _unmarshall(value);
attr.name = name;
// TODO: error management (params undefined)
switch (attr.type) {

View File

@ -25,6 +25,16 @@
<label>{{tr "Description"}}
<textarea class="user_input_description"/>
</label>
<div class="user_input_type_right text">
<label>{{tr "Default value"}}
<input type="text" class="user_input_initial" placeholder="default"/>
</label>
</div>
<div class="user_input_type_right text64">
<label>{{tr "Default value"}}
<input type="text" class="user_input_initial" placeholder="default64"/>
</label>
</div>
<div class="user_input_type_right number">
<label>{{tr "Default value"}}
<input type="number" class="user_input_initial" placeholder="42"/>

View File

@ -2,7 +2,6 @@
"name": "opennebula-sunstone",
"dependencies": {
"flot": "0.8.3",
"ip": "https://github.com/OpenNebula/sunstone-deps.git#50b7927",
"buffer": "https://github.com/anodynos/node2web_buffer.git#91433d2",
"jgrowl": "1.4.2",
"fontawesome": "5.0.7",