Skip to content

Commit

Permalink
F #2410: VM & Host autorefresh Fireedge (#261)
Browse files Browse the repository at this point in the history
* VM & Host autorefresh Fireedge
* Autorefresh authentication

Signed-off-by: Frederick Borges <[email protected]>
  • Loading branch information
Frederick Borges authored Sep 29, 2020
1 parent f77ec0b commit b861775
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 124 deletions.
1 change: 0 additions & 1 deletion share/install_gems/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ group :sunstone do
gem 'memcache-client'
gem 'dalli'
gem 'rotp'
gem 'sinatra-websocket'
end

group :oca do
Expand Down
5 changes: 4 additions & 1 deletion src/sunstone/public/app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ require.config({
"Navigo": "../bower_components/navigo/lib/navigo.min",

/* sprintf */
"sprintf": "../bower_components/sprintf/dist/sprintf.min"
"sprintf": "../bower_components/sprintf/dist/sprintf.min",

/* socket.io-client */
"socket-io-client": "../bower_components/socket.io-client/dist/socket.io.slim"
},
shim: {
/* Tabs */
Expand Down
6 changes: 3 additions & 3 deletions src/sunstone/public/app/sunstone.js
Original file line number Diff line number Diff line change
Expand Up @@ -885,7 +885,7 @@ define(function(require) {

context.html(html);
$.each(SunstoneCfg["tabs"][tabName]["panelInstances"], function(panelName, panel) {
if (!autorefresh || panelName == "vm_info_tab"){
if (!autorefresh){
panel.setup(context);

if(isRefresh && prevPanelStates[panelName] && panel.setState){
Expand Down Expand Up @@ -916,7 +916,7 @@ define(function(require) {
}
};

var _autorefreshVM = function(tabName, info, contextTabId, context) {
var _autorefresh = function(tabName, info, contextTabId, context) {
_insertPanels(tabName, info, contextTabId, context, true);
};

Expand Down Expand Up @@ -1365,7 +1365,7 @@ define(function(require) {

"insertTabs": _insertTabs,
"insertPanels": _insertPanels,
"autorefreshVM": _autorefreshVM,
"autorefresh": _autorefresh,
"getElementRightInfo": _getElementRightInfo,

"showTab": _showTab,
Expand Down
3 changes: 0 additions & 3 deletions src/sunstone/public/app/tabs/vms-tab/panels/info.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ define(function(require) {
var TemplateTableVcenter = require("utils/panel/template-table");
var OpenNebula = require("opennebula");
var Navigation = require("utils/navigation");
var Websocket = require("utils/websocket");
var FireedgeValidator = require("utils/fireedge-validator");

/*
Expand Down Expand Up @@ -202,7 +201,5 @@ define(function(require) {
$(".vmrc-button").hide();
}

Websocket.subscribe(this.element.ID);

}
});
141 changes: 60 additions & 81 deletions src/sunstone/public/app/utils/websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,94 +18,73 @@ define(function (require) {

var Config = require("sunstone-config");
var Sunstone = require('sunstone');


// user config
const wss = Config.autorefreshWSS || 'ws';
const port = Config.autorefreshPort || 9869;
const host = Config.autorefreshIP || '127.0.0.1';

var address = wss + "://" + host + ":" + port + "/ws";
var ws = new WebSocket(address);

var FireedgeValidator = require('utils/fireedge-validator');
var io = require('socket-io-client');

var _start = function () {
ws.addEventListener('open', function (event) {
console.log("Connected to websocket");
ws.readyState = 1;
// Send CSRF token
var msg = {
"STATE": ws.readyState,
"ACTION": "authenticate",
}

ws.send(JSON.stringify(msg));
});

// Listen for messages
ws.addEventListener('message', function (event) {
var vm_info = JSON.parse(event.data);
// console.log(vm_info);
var response = { "VM": vm_info.HOOK_MESSAGE.VM };
var request = {
"request": {
"data": [response.ID],
"method": "show",
"resource": "VM"
if (sessionStorage.getItem(FireedgeValidator.sessionVar) == 'true'){
const socket = io(Config.fireedgeEndpoint, {
path: '/zeromq',
query: {
token: fireedge_token
}
}

// update VM

var TAB_ID = "vms-tab";
var tab = $('#' + TAB_ID);
Sunstone.getDataTable(TAB_ID).updateElement(request, response);
if (Sunstone.rightInfoVisible(tab) && vm_info.HOOK_MESSAGE.RESOURCE_ID == Sunstone.rightInfoResourceId(tab)) {
Sunstone.autorefreshVM(TAB_ID, response);
}

if (vm_info.HOOK_MESSAGE.STATE == "DONE"){
Sunstone.getDataTable(TAB_ID).waitingNodes();
Sunstone.runAction("VM.list", {force: true});
}

});

// Close Socket when close browser or tab.
window.onbeforeunload = function () {
_close();
};
};
});

// Listen for messages
socket.on('zeroMQ', function (event) {
var event_data = event.data;
// console.log(vm_info);
if (event_data && event_data.HOOK_MESSAGE && event_data.HOOK_MESSAGE.HOOK_TYPE && event_data.HOOK_MESSAGE.HOOK_TYPE != 'API'){

var tab_id;
if (event_data.HOOK_MESSAGE.HOOK_OBJECT){
var object = event_data.HOOK_MESSAGE.HOOK_OBJECT;

switch (object) {
case "VM":
tab_id = "vms-tab"
break;
case "HOST":
tab_id = "hosts-tab"
break;
default:
break;
}

var response = {};
response[object] = event_data.HOOK_MESSAGE[object];
var request = {
"request": {
"data": [response.ID],
"method": "show",
"resource": object
}
}

// update VM and HOST
var tab = $('#' + tab_id);
Sunstone.getDataTable(tab_id).updateElement(request, response);
if (Sunstone.rightInfoVisible(tab) && event_data.HOOK_MESSAGE.RESOURCE_ID == Sunstone.rightInfoResourceId(tab)) {
Sunstone.autorefresh(tab_id, response);
}

if (event_data.HOOK_MESSAGE.STATE == "DONE"){
Sunstone.getDataTable(tab_id).waitingNodes();
Sunstone.runAction(object + ".list", {force: true});
}
}
}
});

var _subscribe = function (vm_id, context) {
var msg = {
"SUBSCRIBE": true,
"VM": vm_id
// Close Socket when close browser or tab.
window.onbeforeunload = function () {
socket.close();
};
}

ws.send(JSON.stringify(msg));
};

var _unsubscribe = function (vm_id) {
var msg = {
"SUBSCRIBE": false,
"VM": vm_id
}

ws.send(JSON.stringify(msg));
};

var _close = function () {
ws.onclose = function () { }; // disable onclose handler first
ws.close()
};



var websocket = {
"start": _start,
"subscribe": _subscribe,
"unsubscribe": _unsubscribe,
"close": _close
"start": _start
};

return websocket;
Expand Down
3 changes: 2 additions & 1 deletion src/sunstone/public/bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"wickedpicker": "https://github.com/OpenNebula/sunstone-deps.git#9398b3f",
"guacamole-common-js": "https://github.com/OpenNebula/sunstone-deps.git#1633556e63",
"webauthn-json": "https://registry.npmjs.org/@github/webauthn-json/-/webauthn-json-0.4.1.tgz",
"wmks": "https://github.com/OpenNebula/sunstone-deps.git#cb0251c"
"wmks": "https://github.com/OpenNebula/sunstone-deps.git#cb0251c",
"socket.io-client": "~2.3.0"
},
"authors": [
"Daniel Molina <[email protected]>",
Expand Down
45 changes: 11 additions & 34 deletions src/sunstone/sunstone-server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,7 @@
require 'SunstoneServer'
require 'SunstoneViews'

require 'sinatra-websocket'
require 'eventmachine'
require 'json'
require 'active_support/core_ext/hash'
require 'ffi-rzmq'
require 'net/http'

begin
require "SunstoneWebAuthn"
Expand Down Expand Up @@ -273,35 +269,6 @@
set :erb, :trim => '-'
end

#start Autorefresh server

## 0MQ variables
@context = ZMQ::Context.new(1)
@subscriber = @context.socket(ZMQ::SUB)

## Subscribe to VM changes
@subscriber.setsockopt(ZMQ::SUBSCRIBE, "EVENT VM")
@subscriber.connect($conf[:zeromq_server])

# Create a thread to get ZeroMQ messages
Thread.new do
loop do
key = ''
content = ''

@subscriber.recv_string(key)
@subscriber.recv_string(content)

message = Hash.from_xml(Base64.decode64(content)).to_json

if (key != '')
settings.sockets.each do |client|
client.send(message)
end
end
end
end

$addons = OpenNebulaAddons.new(logger)

DEFAULT_TABLE_ORDER = "desc"
Expand Down Expand Up @@ -535,6 +502,16 @@ def build_session
session[:federation_mode] = active_zone_configuration['FEDERATION/MODE'].upcase
session[:mode] = $conf[:mode]

# Fireedge running
uri = URI($conf[:fireedge_endpoint]+'/api/auth')
user_pass = Base64.decode64(request.env['HTTP_AUTHORIZATION'].split(' ')[1])
username = user_pass.split(":")[0]
password = user_pass.split(":")[1]
params = { :user => username, :pass => password }

res = Net::HTTP.post_form(uri, params)
session[:fireedge_token] = JSON.parse(res.body)['data']['token'] if res.is_a?(Net::HTTPSuccess)

[204, ""]
end

Expand Down
1 change: 1 addition & 0 deletions src/sunstone/views/index.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<% halt 500, "OpenNebula is unreachable" if view.nil? %>
<script type="text/javascript">
var csrftoken = '<%= session[:csrftoken] %>';
var fireedge_token = '<%= session[:fireedge_token] %>';
var view = JSON.parse('<%= view.to_json %>')
var available_views = JSON.parse('["<%=
$views_config.available_views(session[:user], session[:user_gname]).join('","')
Expand Down

0 comments on commit b861775

Please sign in to comment.