1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-24 02:03:52 +03:00

Feature #3471: Create VDC tab for sunstone

This commit is contained in:
Carlos Martín 2015-01-09 16:03:18 +01:00
parent e29d3210a2
commit d7c370ffbc
9 changed files with 712 additions and 2 deletions

View File

@ -1530,7 +1530,8 @@ SUNSTONE_MODELS_JSON_FILES="src/sunstone/models/OpenNebulaJSON/HostJSON.rb \
src/sunstone/models/OpenNebulaJSON/DatastoreJSON.rb \
src/sunstone/models/OpenNebulaJSON/VirtualNetworkJSON.rb \
src/sunstone/models/OpenNebulaJSON/ZoneJSON.rb \
src/sunstone/models/OpenNebulaJSON/SecurityGroupJSON.rb"
src/sunstone/models/OpenNebulaJSON/SecurityGroupJSON.rb \
src/sunstone/models/OpenNebulaJSON/VdcJSON.rb"
SUNSTONE_VIEWS_FILES="src/sunstone/views/index.erb \
src/sunstone/views/login.erb \
@ -1568,7 +1569,8 @@ SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\
src/sunstone/public/js/plugins/oneflow-templates.js \
src/sunstone/public/js/plugins/support-tab.js \
src/sunstone/public/js/plugins/zones-tab.js \
src/sunstone/public/js/plugins/secgroups-tab.js"
src/sunstone/public/js/plugins/secgroups-tab.js \
src/sunstone/public/js/plugins/vdcs-tab.js"
SUNSTONE_ROUTES_FILES="src/sunstone/routes/oneflow.rb \
src/sunstone/routes/vcenter.rb \

View File

@ -5,6 +5,7 @@ available_tabs:
- system-tab
- users-tab
- groups-tab
- vdcs-tab
- acls-tab
- vresources-tab
- vms-tab

View File

@ -5,6 +5,7 @@ enabled_tabs:
system-tab: true
users-tab: true
groups-tab: true
vdcs-tab: true
acls-tab: true
vresources-tab: true
vms-tab: true
@ -97,6 +98,19 @@ tabs:
Group.create_dialog: true
Group.quotas_dialog: true
Group.delete: true
vdcs-tab:
panel_tabs:
vdc_info_tab: true
table_columns:
- 0 # Checkbox
- 1 # ID
- 2 # Name
actions:
Vdc.refresh: true
Vdc.create_dialog: true
Vdc.update_dialog: true
Vdc.delete: true
acls-tab:
panel_tabs:
table_columns:

View File

@ -31,6 +31,7 @@ require 'OpenNebulaJSON/AclJSON'
require 'OpenNebulaJSON/DatastoreJSON'
require 'OpenNebulaJSON/ZoneJSON'
require 'OpenNebulaJSON/SecurityGroupJSON'
require 'OpenNebulaJSON/VdcJSON'
module OpenNebula
class Error

View File

@ -29,4 +29,5 @@ module OpenNebulaJSON
class DatastorePoolJSON < OpenNebula::DatastorePool; include JSONUtils; end
class ZonePoolJSON < OpenNebula::ZonePool; include JSONUtils; end
class SecurityGroupPoolJSON < OpenNebula::SecurityGroupPool; include JSONUtils; end
class VdcPoolJSON < OpenNebula::VdcPool; include JSONUtils; end
end

View File

@ -0,0 +1,114 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
require 'OpenNebulaJSON/JSONUtils'
module OpenNebulaJSON
class VdcJSON < OpenNebula::Vdc
include JSONUtils
def create(template_json)
vdc_hash = parse_json(template_json, 'vdc')
if OpenNebula.is_error?(vdc_hash)
return vdc_hash
end
if vdc_hash['vdc_raw']
template = vdc_hash['vdc_raw']
else
template = template_to_str(vdc_hash)
end
self.allocate(template)
end
def perform_action(template_json)
action_hash = parse_json(template_json, 'action')
if OpenNebula.is_error?(action_hash)
return action_hash
end
rc = case action_hash['perform']
when "add_group" then self.add_group(action_hash['params'])
when "del_group" then self.del_group(action_hash['params'])
when "add_cluster" then self.add_cluster(action_hash['params'])
when "del_cluster" then self.del_cluster(action_hash['params'])
when "add_host" then self.add_host(action_hash['params'])
when "del_host" then self.del_host(action_hash['params'])
when "add_datastore" then self.add_datastore(action_hash['params'])
when "del_datastore" then self.del_datastore(action_hash['params'])
when "add_vnet" then self.add_vnet(action_hash['params'])
when "del_vnet" then self.del_vnet(action_hash['params'])
when "update" then self.update(action_hash['params'])
when "rename" then self.rename(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
end
def add_group(params=Hash.new)
super(params['group_id'].to_i)
end
def del_group(params=Hash.new)
super(params['group_id'].to_i)
end
def add_cluster(params=Hash.new)
super(params['zone_id'].to_i, params['cluster_id'].to_i)
end
def del_cluster(params=Hash.new)
super(params['zone_id'].to_i, params['cluster_id'].to_i)
end
def add_host(params=Hash.new)
super(params['zone_id'].to_i, params['host_id'].to_i)
end
def del_host(params=Hash.new)
super(params['zone_id'].to_i, params['host_id'].to_i)
end
def add_datastore(params=Hash.new)
super(params['zone_id'].to_i, params['ds_id'].to_i)
end
def del_datastore(params=Hash.new)
super(params['zone_id'].to_i, params['ds_id'].to_i)
end
def add_vnet(params=Hash.new)
super(params['zone_id'].to_i, params['vnet_id'].to_i)
end
def del_vnet(params=Hash.new)
super(params['zone_id'].to_i, params['vnet_id'].to_i)
end
def update(params=Hash.new)
super(params['template_raw'])
end
def rename(params=Hash.new)
super(params['name'])
end
end
end

View File

@ -64,6 +64,7 @@ class SunstoneServer < CloudServer
when "datastore" then DatastorePoolJSON.new(client)
when "zone" then ZonePoolJSON.new(client)
when "security_group" then SecurityGroupPoolJSON.new(client, user_flag)
when "vdc" then VdcPoolJSON.new(client)
else
error = Error.new("Error: #{kind} resource not supported")
return [404, error.to_json]
@ -120,6 +121,7 @@ class SunstoneServer < CloudServer
when "datastore" then DatastoreJSON.new(Acl.build_xml, @client)
when "zone" then ZoneJSON.new(Zone.build_xml, @client)
when "security_group" then SecurityGroupJSON.new(SecurityGroup.build_xml, @client)
when "vdc" then VdcJSON.new(Vdc.build_xml, @client)
else
error = Error.new("Error: #{kind} resource not supported")
return [404, error.to_json]
@ -440,6 +442,7 @@ class SunstoneServer < CloudServer
when "datastore" then DatastoreJSON.new_with_id(id, @client)
when "zone" then ZoneJSON.new_with_id(id, @client)
when "security_group" then SecurityGroupJSON.new_with_id(id, @client)
when "vdc" then VdcJSON.new_with_id(id, @client)
else
error = Error.new("Error: #{kind} resource not supported")
return error

View File

@ -1580,6 +1580,86 @@ var OpenNebula = {
}
},
"Vdc" : {
"resource" : "VDC",
"create" : function(params){
OpenNebula.Action.create(params,OpenNebula.Vdc.resource);
},
"del" : function(params){
OpenNebula.Action.del(params,OpenNebula.Vdc.resource);
},
"list" : function(params){
OpenNebula.Action.list(params,OpenNebula.Vdc.resource);
},
"show" : function(params){
OpenNebula.Action.show(params,OpenNebula.Vdc.resource);
},
"update" : function(params){
var action_obj = {"template_raw" : params.data.extra_param };
OpenNebula.Action.simple_action(params,
OpenNebula.Vdc.resource,
"update",
action_obj);
},
"fetch_template" : function(params){
OpenNebula.Action.show(params,OpenNebula.Vdc.resource,"template");
},
"rename" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,
OpenNebula.Vdc.resource,
"rename",
action_obj);
},
"add_group" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,OpenNebula.Vdc.resource,"add_group",action_obj);
},
"del_group" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,OpenNebula.Vdc.resource,"del_group",action_obj);
},
"add_cluster" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,OpenNebula.Vdc.resource,"add_cluster",action_obj);
},
"del_cluster" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,OpenNebula.Vdc.resource,"del_cluster",action_obj);
},
"add_host" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,OpenNebula.Vdc.resource,"add_host",action_obj);
},
"del_host" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,OpenNebula.Vdc.resource,"del_host",action_obj);
},
"add_datastore" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,OpenNebula.Vdc.resource,"add_datastore",action_obj);
},
"del_datastore" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,OpenNebula.Vdc.resource,"del_datastore",action_obj);
},
"add_vnet" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,OpenNebula.Vdc.resource,"add_vnet",action_obj);
},
"del_vnet" : function(params){
var action_obj = params.data.extra_param;
OpenNebula.Action.simple_action(params,OpenNebula.Vdc.resource,"del_vnet",action_obj);
}
},
"Marketplace" : {
"resource" : "MARKETPLACE",

View File

@ -0,0 +1,494 @@
/* -------------------------------------------------------------------------- */
/* Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs */
/* */
/* 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. */
/* -------------------------------------------------------------------------- */
var create_vdc_wizard_html =
'<form data-abide="ajax" id="create_vdc_form_wizard" class="custom creation">\
<div>\
<dl id="vdc_create_tabs" class="tabs right-info-tabs text-center" data-tab>\
<dd class="active"><a href="#vdcCreateGeneralTab"><i class="fa fa-globe"></i><br>'+tr("General")+'</a></dd>\
</dl>\
<div id="vdc_create_tabs_content" class="tabs-content">\
<div class="content active" id="vdcCreateGeneralTab">\
<div class="row">\
<div class="large-6 columns">\
<label for="name" >' + tr("Name") + ':\
<span class="tip">'+tr("Name that the Virtual Data Center will get for description purposes.")+'</span>\
</label>\
<input type="text" wizard_field="NAME" required name="name" id="name"/>\
</div>\
</div>\
<div class="row">\
<div class="large-6 columns">\
<label for="DESCRIPTION" >' + tr("Description") + ':\
<span class="tip">'+tr("Description of the Virtual Data Center")+'</span>\
</label>\
<textarea type="text" wizard_field="DESCRIPTION" id="DESCRIPTION" name="DESCRIPTION"/>\
</div>\
</div>\
<br>\
<div class="row">\
<div class="large-12 columns">\
<span>' + tr("Custom attributes") + '</span>\
<br>\
<br>\
</div>\
</div>'+
customTagsHtml()+'\
</div>\
</div>\
</div>\
</form>';
var create_vdc_advanced_html =
'<form data-abide="ajax" id="create_vdc_form_advanced" class="custom creation">' +
'<div class="row">' +
'<div class="large-12 columns">' +
'<p>'+tr("Write the Virtual Data Center template here")+'</p>' +
'</div>' +
'</div>' +
'<div class="row">' +
'<div class="large-12 columns">' +
'<textarea id="template" rows="15" required></textarea>' +
'</div>' +
'</div>' +
'</form>';
var dataTable_vdcs;
//Setup actions
var vdc_actions = {
"Vdc.create" : {
type: "create",
call: OpenNebula.Vdc.create,
callback: function(request, response) {
$("a[href=back]", $("#vdcs-tab")).trigger("click");
popFormDialog("create_vdc_form", $("#vdcs-tab"));
addVdcElement(request, response);
notifyCustom(tr("Virtual Data Center created"), " ID: " + response.VDC.ID, false);
},
error: onError
},
"Vdc.create_dialog" : {
type: "custom",
call: function(){
Sunstone.popUpFormPanel("create_vdc_form", "vdcs-tab", "create", true, function(context){
refreshSecurityGroupTableSelect(context, "vdc_create");
$("#default_sg_warning").show();
$("input#name",context).focus();
});
}
},
"Vdc.list" : {
type: "list",
call: OpenNebula.Vdc.list,
callback: updateVdcsView,
error: onError
},
"Vdc.show" : {
type: "single",
call: OpenNebula.Vdc.show,
callback: function(request, response) {
updateVdcElement(request, response);
if (Sunstone.rightInfoVisible($("#vdcs-tab"))) {
updateVdcInfo(request, response);
}
},
error: onError
},
"Vdc.refresh" : {
type: "custom",
call: function(){
var tab = dataTable_vdcs.parents(".tab");
if (Sunstone.rightInfoVisible(tab)) {
Sunstone.runAction("Vdc.show", Sunstone.rightInfoResourceId(tab))
} else {
waitingNodes(dataTable_vdcs);
Sunstone.runAction("Vdc.list", {force: true});
}
}
},
"Vdc.delete" : {
type: "multiple",
call: OpenNebula.Vdc.del,
callback: deleteVdcElement,
elements: vdcElements,
error: onError
},
"Vdc.rename" : {
type: "single",
call: OpenNebula.Vdc.rename,
callback: function(request) {
Sunstone.runAction('Vdc.show',request.request.data[0][0]);
},
error: onError
},
"Vdc.update_dialog" : {
type: "custom",
call: function(){
var selected_nodes = getSelectedNodes(dataTable_vdcs);
if ( selected_nodes.length != 1 ) {
notifyMessage("Please select one (and just one) Virtual Data Center to update.");
return false;
}
var resource_id = ""+selected_nodes[0];
Sunstone.runAction("Vdc.show_to_update", resource_id);
}
},
"Vdc.show_to_update" : {
type: "single",
call: OpenNebula.Vdc.show,
callback: function(request, response) {
// TODO: global var, better use jquery .data
vdc_to_update_id = response.VDC.ID;
Sunstone.popUpFormPanel("create_vdc_form", "vdcs-tab", "update", true, function(context){
fillVdcUpdateFormPanel(response.VDC, context);
$("#default_sg_warning").hide();
});
},
error: onError
},
"Vdc.update" : {
type: "single",
call: OpenNebula.Vdc.update,
callback: function(request, response){
$("a[href=back]", $("#vdcs-tab")).trigger("click");
popFormDialog("create_vdc_form", $("#vdcs-tab"));
notifyMessage(tr("Virtual Data Center updated correctly"));
},
error: function(request, response){
popFormDialog("create_vdc_form", $("#vdcs-tab"));
onError(request, response);
}
},
"Vdc.update_template" : {
type: "single",
call: OpenNebula.Vdc.update,
callback: function(request) {
Sunstone.runAction('Vdc.show',request.request.data[0][0]);
},
error: onError
}
};
var vdc_buttons = {
"Vdc.refresh" : {
type: "action",
layout: "refresh",
alwaysActive: true
},
// "Sunstone.toggle_top" : {
// type: "custom",
// layout: "top",
// alwaysActive: true
// },
"Vdc.create_dialog" : {
type: "create_dialog",
layout: "create"
},
"Vdc.update_dialog" : {
type: "action",
layout: "main",
text: tr("Update")
},
"Vdc.delete" : {
type: "confirm",
layout: "del",
text: tr("Delete")
}
}
var vdc_info_panel = {
"vdc_info_tab" : {
title: tr("Virtual Data Center information"),
content: ""
}
}
var vdcs_tab = {
title: tr("Virtual Data Centers"),
resource: 'Vdc',
buttons: vdc_buttons,
tabClass: "subTab",
parentTab: "system-tab",
search_input: '<input id="vdc_search" type="text" placeholder="'+tr("Search")+'" />',
list_header: '<i class="fa fa-fw fa-globe"></i>&emsp;'+tr("Virtual Data Centers"),
info_header: '<i class="fa fa-fw fa-globe"></i>&emsp;'+tr("Virtual Data Center"),
subheader: '<span class="total_vdcs"/> <small>'+tr("TOTAL")+'</small>',
table: '<table id="datatable_vdcs" class="datatable twelve">\
<thead>\
<tr>\
<th class="check"><input type="checkbox" class="check_all" value=""></input></th>\
<th>'+tr("ID")+'</th>\
<th>'+tr("Name")+'</th>\
</tr>\
</thead>\
<tbody id="tbodyvdcs">\
</tbody>\
</table>',
forms: {
"create_vdc_form": {
actions: {
create: {
title: tr("Create Virtual Data Center"),
submit_text: tr("Create")
},
update: {
title: tr("Update Virtual Data Center"),
submit_text: tr("Update"),
reset_button: false
}
},
wizard_html: create_vdc_wizard_html,
advanced_html: create_vdc_advanced_html,
setup: initialize_create_vdc_dialog
}
}
}
Sunstone.addActions(vdc_actions);
Sunstone.addMainTab('vdcs-tab',vdcs_tab);
Sunstone.addInfoPanel('vdc_info_panel',vdc_info_panel);
// return list of selected elements in list
function vdcElements(){
return getSelectedNodes(dataTable_vdcs);
}
//returns an array with the VDC information fetched from the JSON object
function vdcElementArray(vdc_json){
var vdc = vdc_json.VDC;
return [
'<input class="check_item" type="checkbox" id="vdc_'+vdc.ID+'" name="selected_items" value="'+vdc.ID+'"/>',
vdc.ID,
vdc.NAME
];
}
//Callback to update a vdc element after an action on it
function updateVdcElement(request, vdc_json){
id = vdc_json.VDC.ID;
element = vdcElementArray(vdc_json);
updateSingleElement(element,dataTable_vdcs,'#vdc_'+id);
}
//Callback to delete a vdc element from the table
function deleteVdcElement(req){
deleteElement(dataTable_vdcs,'#vdc_'+req.request.data);
}
//Callback to add a new element
function addVdcElement(request,vdc_json){
var element = vdcElementArray(vdc_json);
addElement(element,dataTable_vdcs);
}
//updates the list of vdcs
function updateVdcsView(request, vdc_list){
var vdc_list_array = [];
$.each(vdc_list,function(){
vdc_list_array.push(vdcElementArray(this));
});
updateView(vdc_list_array,dataTable_vdcs);
$(".total_vdcs").text(vdc_list.length);
}
//updates the information panel tabs and pops the panel up
function updateVdcInfo(request,vdc){
var vdc_info = vdc.VDC;
$(".resource-info-header", $("#vdcs-tab")).html(vdc_info.NAME);
var info_tab_content =
'<div class="row">\
<div class="large-6 columns">\
<table id="info_vdc_table" class="dataTable extended_table">\
<thead>\
<tr><th colspan="3">'+tr("Information")+'</th></tr>\
</thead>\
<tr>\
<td class="key_td">'+tr("ID")+'</td>\
<td class="value_td">'+vdc_info.ID+'</td>\
<td></td>\
</tr>'+
insert_rename_tr(
'vdcs-tab',
"Vdc",
vdc_info.ID,
vdc_info.NAME)+
'</table>\
</div>\
</div>\
<div class="row">\
<div class="large-9 columns">' +
insert_extended_template_table(vdc_info.TEMPLATE,
"Vdc",
vdc_info.ID,
tr("Attributes")) +
'</div>\
</div>';
var info_tab = {
title : tr("Info"),
icon: "fa-info-circle",
content: info_tab_content
};
Sunstone.updateInfoPanelTab("vdc_info_panel","vdc_info_tab",info_tab);
Sunstone.popUpInfoPanel("vdc_info_panel", "vdcs-tab");
}
function initialize_create_vdc_dialog(dialog) {
setupCustomTags($("#vdcCreateGeneralTab", dialog));
dialog.foundation();
//Process form
$('#create_vdc_form_wizard',dialog).on('invalid.fndtn.abide', function () {
notifyError(tr("One or more required fields are missing or malformed."));
popFormDialog("create_vdc_form", $("#vdcs-tab"));
}).on('valid.fndtn.abide', function() {
//Fetch values
var vdc_json = {};
retrieveWizardFields($("#vdcCreateGeneralTab", dialog), vdc_json);
retrieveCustomTags($("#vdcCreateGeneralTab", dialog), vdc_json);
if ($('#create_vdc_form_wizard',dialog).attr("action") == "create") {
vdc_json = {
"vdc" : vdc_json
};
Sunstone.runAction("Vdc.create",vdc_json);
return false;
} else if ($('#create_vdc_form_wizard',dialog).attr("action") == "update") {
Sunstone.runAction("Vdc.update", vdc_to_update_id, convert_template_to_string(vdc_json));
return false;
}
});
$('#create_vdc_form_advanced',dialog).on('invalid.fndtn.abide', function () {
notifyError(tr("One or more required fields are missing or malformed."));
popFormDialog("create_vdc_form", $("#vdcs-tab"));
}).on('valid.fndtn.abide', function() {
if ($('#create_vdc_form_advanced',dialog).attr("action") == "create") {
var template = $('textarea#template',dialog).val();
var vdc_json = {vdc: {vdc_raw: template}};
Sunstone.runAction("Vdc.create",vdc_json);
return false;
} else if ($('#create_vdc_form_advanced',dialog).attr("action") == "update") {
var template_raw = $('textarea#template',dialog).val();
Sunstone.runAction("Vdc.update",vdc_to_update_id,template_raw);
return false;
}
});
setupTips(dialog);
}
function fillVdcUpdateFormPanel(vdc, dialog){
// Populates the Avanced mode Tab
$('#template',dialog).val(convert_template_to_string(vdc.TEMPLATE).replace(/^[\r\n]+$/g, ""));
$('[wizard_field="NAME"]',dialog).val(
escapeDoubleQuotes(htmlDecode( vdc.NAME ))).
prop("disabled", true).
prop('wizard_field_disabled', true);
fillWizardFields($("#vdcCreateGeneralTab", dialog), vdc.TEMPLATE);
// Delete so these attributes don't end in the custom tags table also
var fields = $('[wizard_field]', dialog);
fields.each(function(){
var field = $(this);
var field_name = field.attr('wizard_field');
delete vdc.TEMPLATE[field_name];
});
fillCustomTags($("#vdcCreateGeneralTab", dialog), vdc.TEMPLATE);
}
//The DOM is ready and the ready() from sunstone.js
//has been executed at this point.
$(document).ready(function(){
var tab_name = 'vdcs-tab';
if (Config.isTabEnabled(tab_name)) {
dataTable_vdcs = $("#datatable_vdcs",main_tabs_context).dataTable({
"bSortClasses": false,
"bDeferRender": true,
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "35px", "aTargets": [0] },
{ "bVisible": true, "aTargets": Config.tabTableColumns(tab_name)},
{ "bVisible": false, "aTargets": ['_all']}
]
});
$('#vdc_search').keyup(function(){
dataTable_vdcs.fnFilter( $(this).val() );
})
dataTable_vdcs.on('draw', function(){
recountCheckboxes(dataTable_vdcs);
})
Sunstone.runAction("Vdc.list");
initCheckAllBoxes(dataTable_vdcs);
tableCheckboxesListener(dataTable_vdcs);
infoListener(dataTable_vdcs,'Vdc.show');
$('div#vdcs_tab div.legend_div').hide();
dataTable_vdcs.fnSort( [ [1,config['user_config']['table_order']] ] );
}
});