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

F #3969: Support for RDP links in sunstone (#4175)

(cherry picked from commit 31880fb5a652d6dc520368ddcdf31f413215b2f4)
This commit is contained in:
Sergio Betanzos 2020-02-11 14:33:34 +01:00 committed by Tino Vazquez
parent 25594a55c3
commit 597d3ec20c
No known key found for this signature in database
GPG Key ID: 2FE9C32E94AEABBE
13 changed files with 271 additions and 8 deletions

View File

@ -671,6 +671,7 @@ define(function(require) {
"isDiskGraphsSupported": isDiskGraphsSupported,
"isNICAttachSupported": isNICAttachSupported,
"isVNCSupported": isVNCSupported,
"isRDPSupported": isRDPSupported,
"isSPICESupported": isSPICESupported,
"getName": function(id){
return OpenNebulaAction.getName(id, RESOURCE);
@ -799,7 +800,11 @@ define(function(require) {
$.each(nic, function(index, value) {
$.each(NIC_IP_ATTRS, function(j, attr){
if (value[attr]) {
ips.push(value[attr]);
if ( attr === "IP" && value["RDP"] === "YES") {
ips.push(value[attr] + "&nbsp;<small>RDP</small>");
} else {
ips.push(value[attr]);
}
}
});
});
@ -866,5 +871,14 @@ define(function(require) {
$.inArray(state, VNC_STATES) != -1);
}
// returns true if the RDP button should be enabled
function isRDPSupported(element) {
return ( element.TEMPLATE &&
element.TEMPLATE.NIC &&
element.TEMPLATE.NIC.length > 0 &&
element.TEMPLATE.NIC.filter(nic => nic.RDP && nic.RDP == "YES")
);
}
return VM;
});

View File

@ -438,6 +438,11 @@ define(function(require) {
text = button.text;
buttonCode = "<li><a class=\"" + strClass.join(" ") + "\" href=\"" + buttonName + "\">" + text + "</a></li>";
break;
case "vmsremote_buttons":
buttonContext = $("#" + customId + "vmsremote_buttons", buttonsRow);
text = button.text;
buttonCode = "<li><a class=\"" + strClass.join(" ") + "\" href=\"" + buttonName + "\">" + text + "</a></li>";
break;
case "more_select":
buttonContext = $("#" + customId + "more_buttons", buttonsRow);
text = button.text;
@ -502,6 +507,10 @@ define(function(require) {
$("button[data-toggle=" + customId + "vmsmigration_buttons]", actionBlock).remove();
}
if ($("#" + customId + "vmsremote_buttons li", actionBlock).length == 0) {
$("button[data-toggle=" + customId + "vmsremote_buttons]", actionBlock).remove();
}
if ($("#" + customId + "vmsdelete_buttons li", actionBlock).length == 0) {
$("button[data-toggle=" + customId + "vmsdelete_buttons]", actionBlock).remove();
}

View File

@ -41,6 +41,11 @@
<span id="{{customId}}refresh_buttons" class=" only-sunstone-info only-sunstone-list"></span>
</span>
<span>
<button type='button' data-toggle='{{customId}}vmsremote_buttons' class='only-sunstone-info top_button button dropdown'>
<i class='fas fa-desktop'/>
</button>
<ul id='{{customId}}vmsremote_buttons' class='only-sunstone-info dropdown-pane menu vertical' data-dropdown></ul>
<span id="{{customId}}main_buttons" class="only-sunstone-info only-sunstone-list"></span>
<span id="{{customId}}vmsplay_buttons" class='only-sunstone-info only-sunstone-list'></span>

View File

@ -70,6 +70,7 @@ define(function(require) {
WizardTab.prototype.renameTabLinks = _renameTabLinks;
WizardTab.prototype.addNicTab = _addNicTab;
WizardTab.prototype.notify = _notify;
WizardTab.prototype.enableRDP = _enableRDP;
return WizardTab;
@ -208,6 +209,7 @@ define(function(require) {
});
that.renameTabLinks(context);
that.enableRDP(context);
if (templateJSON.NIC) {
delete templateJSON.NIC;
@ -279,6 +281,7 @@ define(function(require) {
content.attr("nicId", that.numberOfNics);
that.renameTabLinks(context);
that.enableRDP(context);
that.nicTabObjects[that.numberOfNics] = nicTab;
// close icon: removing the tab on click
@ -302,6 +305,7 @@ define(function(require) {
}
that.renameTabLinks(context);
that.enableRDP(context);
that.numberOfNics --;
});
}
@ -322,6 +326,13 @@ define(function(require) {
}
}
function _enableRDP(context) {
const canRDP = $("fieldset#rdp_connection input[type='checkbox']:not(#" + that.nicTabId + "_rdp):checked", context).length === 0;
if (canRDP) $("fieldset#rdp_connection").show();
else $("fieldset#rdp_connection", that.context).hide();
}
function _notify(context, templateJSON) {
if (templateJSON.VROUTER == "YES"){
while($("i.remove-tab", context).length > 0){

View File

@ -307,6 +307,11 @@ define(function(require) {
context.on("change", "input[name='" + that.nicTabId + "_rank_select']", function() {
$("input#"+that.nicTabId+"_SCHED_RANK", context).val(this.value);
});
context.on("change", "#" + that.nicTabId + "_rdp", function() {
const isRDPActivated = $(this).prop('checked');
_hide_rdp(that.nicTabId, isRDPActivated, context);
});
}
function _retrieve(context) {
@ -356,6 +361,10 @@ define(function(require) {
nicJSON["PARENT"] = $("#" + this.nicTabId + "_alias_parent", context).val();
}
if($("input#" + this.nicTabId + "_rdp", context).prop("checked")) {
nicJSON["RDP"] = "YES";
}
return nicJSON;
}
@ -464,6 +473,14 @@ define(function(require) {
}
}
const isRDPActivated = (
templateJSON["RDP"] &&
templateJSON["RDP"] === "YES" &&
$("fieldset#rdp_connection input:not(#" + that.nicTabId + "_rdp):checked", context).length === 0
) ? true : false;
$("input#" + this.nicTabId + "_rdp", context).prop("checked", isRDPActivated);
WizardFields.fill(context, templateJSON);
}
@ -501,4 +518,14 @@ define(function(require) {
}
});
}
function _hide_rdp(nicTabId, isRDPActivated, context) {
$("#template_create_network_tabs_content > div:not(#" + nicTabId + ") fieldset#rdp_connection", context).each(function() {
if (isRDPActivated) {
$(this).hide();
} else {
$(this).show();
}
});
}
});

View File

@ -48,6 +48,19 @@
{{{tip (tr "The Schedule will decide which is the best virtual network")}}}
</label>
</fieldset>
<fieldset id="rdp_connection">
<legend>{{tr "RDP connection"}}</legend>
<div class="switch left">
<input class="switch-input" id="{{nicTabId}}_rdp" type="checkbox">
<label class="switch-paddle" for="{{nicTabId}}_rdp">
</label>
</div>
<label class="left">
&nbsp;&nbsp;
{{tr "Activate"}}
{{{tip (tr "RDP will be activate in this network")}}}
</label>
</fieldset>
</div>
</div>
<div class="auto">

View File

@ -276,15 +276,21 @@ define(function(require) {
var pcis = [];
var alias = [];
var rdp = true;
$.each(networks, function(){
if (this.TYPE == "NIC"){
pcis.push(this);
} else if (this.PARENT) {
alias.push(this);
} else {
(rdp && this.RDP == "YES")
? rdp = false
: delete this["RDP"];
nics.push(this);
}
});
debugger
tmp_json.NIC = nics;
tmp_json.NIC_ALIAS = alias;
@ -337,11 +343,11 @@ define(function(require) {
$.extend(tmp_json, CapacityInputs.retrieveChanges(capacityContext));
extra_info["template"] = tmp_json;
for (var i = 0; i < n_times_int; i++) {
extra_info["vm_name"] = vm_name.replace(/%i/gi, i); // replace wildcard
for (var i = 0; i < n_times_int; i++) {
extra_info["vm_name"] = vm_name.replace(/%i/gi, i); // replace wildcard
Sunstone.runAction("Template."+action, [template_id], extra_info);
}
Sunstone.runAction("Template."+action, [template_id], extra_info);
}
});
return false;

View File

@ -23,6 +23,7 @@ define(function(require) {
var CommonActions = require('utils/common-actions');
var Vnc = require('utils/vnc');
var Spice = require('utils/spice');
var Rdp = require('utils/rdp');
var TAB_ID = require('./tabId');
var CREATE_DIALOG_ID = require('./form-panels/create/formPanelId');
@ -171,6 +172,33 @@ define(function(require) {
dialog.show();
}
},
"VM.save_rdp" : {
type: "custom",
call: function() {
var vm = Sunstone.getElementRightInfo(TAB_ID);
if (vm && vm.NAME && vm.TEMPLATE && Array.isArray(vm.TEMPLATE.NIC)) {
var name = vm.NAME;
var nic = vm.TEMPLATE.NIC.find(n => n.RDP === "YES");
var credentials = {};
if (vm.TEMPLATE.CONTEXT) {
var context = vm.TEMPLATE.CONTEXT;
for (var prop in context) {
var propUpperCase = String(prop).toUpperCase();
(propUpperCase === "USERNAME" || propUpperCase === "PASSWORD")
&& (credentials[propUpperCase] = context[prop]);
}
}
nic && Rdp.downloadFile(nic.IP, name, credentials);
} else {
Notifier.notifyError(Locale.tr("RDP file error"));
return false;
}
}
},
"VM.startvnc" : {
type: "custom",
call: function() {

View File

@ -196,9 +196,16 @@ define(function(require) {
},
"VM.startvnc" : {
type: "action",
text: '<i class="fas fa-desktop"/> ' + Locale.tr("VNC"),
text: Locale.tr("VNC"),
layout: "vmsremote_buttons",
custom_classes: "only-sunstone-info vnc-sunstone-info"
},
"VM.save_rdp" : {
type: "action",
text: Locale.tr("RDP"),
layout: "vmsremote_buttons",
custom_classes: "only-sunstone-info rdp-sunstone-info"
},
"VM.startspice" : {
type: "action",
text: '<i class="fas fa-desktop"/> ' + Locale.tr("SPICE"),

View File

@ -48,6 +48,13 @@ define(function(require) {
$(".vnc-sunstone-info").hide();
}
// Enable / disable rdp button
if (OpenNebulaVM.isRDPSupported(element)) {
$(".rdp-sunstone-info").show();
} else {
$(".rdp-sunstone-info").hide();
}
if (OpenNebulaVM.isSPICESupported(element)) {
$(".spice-sunstone-info").show();
} else {

View File

@ -439,6 +439,12 @@ define(function(require) {
$(".SCHED_RANK", dd_context).val(this.value);
});
$("input#provision_accordion_dd_" + provision_nic_accordion_dd_id + "_rdp", dd_context).on("change", function() {
const isRDPActivated = $(this).prop('checked');
const idAccordion = "#provision_accordion_dd_" + dd_context["dd_id"];
_hide_rdp(idAccordion, isRDPActivated, context);
});
if ( options.nic && options.nic["NETWORK_MODE"] && options.nic["NETWORK_MODE"] === "auto" ) {
$("input#provision_accordion_dd_"+provision_nic_accordion_dd_id+"_network_mode", dd_context).prop("checked", true);
@ -492,6 +498,17 @@ define(function(require) {
_fill_alias(options.nic.PARENT);
}
// fill rdp connection
const isRDPActivated = (
options.nic &&
options.nic["RDP"] &&
options.nic["RDP"] === "YES" &&
$("fieldset#rdp_connection input:not(#provision_accordion_dd_" + provision_nic_accordion_dd_id + "_rdp):checked", context).length === 0
) ? true : false;
$("input#provision_accordion_dd_" + provision_nic_accordion_dd_id + "_rdp", context).prop("checked", isRDPActivated);
_enableRDP("#provision_accordion_dd_" + provision_nic_accordion_dd_id, context)
provision_nic_accordion_dd_id += 1;
vnetsTable.initialize();
@ -535,11 +552,13 @@ define(function(require) {
dd_context.remove();
var index = _nics.findIndex(nic => nic.NAME === ("NIC" + dd_context["nic_id"]));
_nics.splice(index, 1);
nicId --;
_enableRDP("#provision_accordion_dd_"+dd_context["nic_id"], context)
return false;
});
@ -590,6 +609,8 @@ define(function(require) {
_generate_provision_network_table($(".accordion", context), options);
nicId ++;
_enableRDP("#provision_accordion_dd_" + provision_nic_accordion_dd_id, context)
});
if (options.click_add_button == true){
@ -656,4 +677,21 @@ define(function(require) {
}
});
}
function _hide_rdp(idAccordion, isRDPActivated, context) {
$(".accordion-item > div:not(" + idAccordion + ") fieldset#rdp_connection", context).each(function() {
if (isRDPActivated) {
$(this).hide();
} else {
$(this).show();
}
});
}
function _enableRDP(idAccordion, context) {
const canRDP = $("fieldset#rdp_connection input[type='checkbox']:not(" + idAccordion + "_rdp):checked", context).length === 0;
if (canRDP) $("fieldset#rdp_connection", context).has("input:not(:checked)").show();
else $("fieldset#rdp_connection", context).has("input:not(:checked)").hide();
}
});

View File

@ -57,6 +57,21 @@
</label>
</div>
</fieldset>
<fieldset id="rdp_connection">
<legend>{{tr "RDP connection"}}</legend>
<div id="provision_accordion_dd_{{provision_nic_accordion_dd_id}}_rdp_wrapper">
<div class="switch left">
<input class="switch-input" id="provision_accordion_dd_{{provision_nic_accordion_dd_id}}_rdp" type="checkbox">
<label class="switch-paddle" for="provision_accordion_dd_{{provision_nic_accordion_dd_id}}_rdp">
</label>
</div>
<label class="left">
&nbsp;&nbsp;
{{tr "Activate"}}
{{{tip (tr "RDP will be activate in this network")}}}
</label>
</div>
</fieldset>
</div>
<div class="auto">
<fieldset>

View File

@ -0,0 +1,83 @@
/* -------------------------------------------------------------------------- */
/* 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() {
return {
"fileText": _fileText,
"downloadFile": _downloadFile
};
function _downloadFile(ip, name, credentials) {
var file = _fileText(ip, credentials.USERNAME, credentials.PASSWORD);
var link = $("<a/>", {
href: 'data:text/plain;charset=utf-8,' + encodeURIComponent(file),
download: name + ".rdp",
}).css({
display: 'none',
}).appendTo("body");
link.get(0).click(function(e) {
e.preventDefault();
});
link.remove();
}
function _fileText(ip, username, password) {
let file = ""
file += "screen mode id:i:2\n";
file += "desktopwidth:i:1280\n";
file += "desktopheight:i:960\n";
file += "session bpp:i:32\n";
file += "winposstr:s:2,3,1430,104,2230,704\n";
file += "compression:i:1\n";
file += "keyboardhook:i:2\n";
file += "displayconnectionbar:i:1\n";
file += "disable wallpaper:i:1\n";
file += "disable full window drag:i:1\n";
file += "allow desktop composition:i:0\n";
file += "allow font smoothing:i:0\n";
file += "disable menu anims:i:1\n";
file += "disable themes:i:0\n";
file += "disable cursor setting:i:0\n";
file += "bitmapcachepersistenable:i:1\n";
file += "full address:s:" + ip + "\n";
if (username) { file += "username:s:" + username + "\n"; }
if (password) { file += "password:s:" + password + "\n"; }
file += "audiomode:i:0\n";
file += "redirectprinters:i:1\n";
file += "redirectcomports:i:0\n";
file += "redirectsmartcards:i:1\n";
file += "redirectclipboard:i:1\n";
file += "redirectposdevices:i:0\n";
file += "autoreconnection enabled:i:1\n";
file += "authentication level:i:0\n";
file += "prompt for credentials:i:0\n";
file += "negotiate security layer:i:1\n";
file += "remoteapplicationmode:i:0\n";
file += "alternate shell:s:\n";
file += "shell working directory:s:\n";
file += "gatewayhostname:s:\n";
file += "gatewayusagemethod:i:4\n";
file += "gatewaycredentialssource:i:4\n";
file += "gatewayprofileusagemethod:i:0\n";
file += "promptcredentialonce:i:1\n";
return file;
}
});