diff --git a/install.sh b/install.sh index 0e232e4e53..b9e0ac75c7 100755 --- a/install.sh +++ b/install.sh @@ -262,6 +262,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/vmm/az \ $VAR_LOCATION/remotes/vnm \ $VAR_LOCATION/remotes/vnm/802.1Q \ + $VAR_LOCATION/remotes/vnm/vxlan \ $VAR_LOCATION/remotes/vnm/dummy \ $VAR_LOCATION/remotes/vnm/ebtables \ $VAR_LOCATION/remotes/vnm/fw \ @@ -449,6 +450,7 @@ INSTALL_FILES=( DATASTORE_DRIVER_DEV_SCRIPTS:$VAR_LOCATION/remotes/datastore/dev NETWORK_FILES:$VAR_LOCATION/remotes/vnm NETWORK_8021Q_FILES:$VAR_LOCATION/remotes/vnm/802.1Q + NETWORK_VXLAN_FILES:$VAR_LOCATION/remotes/vnm/vxlan NETWORK_DUMMY_FILES:$VAR_LOCATION/remotes/vnm/dummy NETWORK_EBTABLES_FILES:$VAR_LOCATION/remotes/vnm/ebtables NETWORK_FW_FILES:$VAR_LOCATION/remotes/vnm/fw @@ -941,6 +943,7 @@ NETWORK_FILES="src/vnm_mad/remotes/lib/vnm_driver.rb \ src/vnm_mad/remotes/lib/address.rb \ src/vnm_mad/remotes/lib/command.rb \ src/vnm_mad/remotes/lib/vm.rb \ + src/vnm_mad/remotes/lib/vlan.rb \ src/vnm_mad/remotes/lib/security_groups.rb \ src/vnm_mad/remotes/lib/security_groups_iptables.rb \ src/vnm_mad/remotes/lib/nic.rb" @@ -948,7 +951,13 @@ NETWORK_FILES="src/vnm_mad/remotes/lib/vnm_driver.rb \ NETWORK_8021Q_FILES="src/vnm_mad/remotes/802.1Q/clean \ src/vnm_mad/remotes/802.1Q/post \ src/vnm_mad/remotes/802.1Q/pre \ - src/vnm_mad/remotes/802.1Q/vlan_driver.rb" + src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb" + +NETWORK_VXLAN_FILES="src/vnm_mad/remotes/vxlan/clean \ + src/vnm_mad/remotes/vxlan/post \ + src/vnm_mad/remotes/vxlan/pre \ + src/vnm_mad/remotes/vxlan/vxlan_driver.rb" + NETWORK_DUMMY_FILES="src/vnm_mad/remotes/dummy/clean \ src/vnm_mad/remotes/dummy/post \ diff --git a/src/cli/onevcenter b/src/cli/onevcenter index 4a73a0bb8d..97eac60ac5 100755 --- a/src/cli/onevcenter +++ b/src/cli/onevcenter @@ -182,7 +182,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do next if STDIN.gets.strip.downcase != 'y' if tmps.empty? - STDOUT.print " No VM Templates found in #{dc}...\n\n" + STDOUT.print " No new VM Templates found in #{dc}...\n\n" next end @@ -253,7 +253,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do next if STDIN.gets.strip.downcase != 'y' if tmps.empty? - STDOUT.print " No Networks found in #{dc}...\n\n" + STDOUT.print " No new Networks found in #{dc}...\n\n" next end diff --git a/src/sunstone/etc/sunstone-views/admin.yaml b/src/sunstone/etc/sunstone-views/admin.yaml index 7c582db228..9dcdec369e 100644 --- a/src/sunstone/etc/sunstone-views/admin.yaml +++ b/src/sunstone/etc/sunstone-views/admin.yaml @@ -155,6 +155,7 @@ tabs: - 9 # IPs #- 10 # Start Time - 11 # VNC + #- 12 # Hidden Template actions: VM.refresh: true VM.create_dialog: true diff --git a/src/sunstone/etc/sunstone-views/user.yaml b/src/sunstone/etc/sunstone-views/user.yaml index a79973bdce..52b09bd947 100644 --- a/src/sunstone/etc/sunstone-views/user.yaml +++ b/src/sunstone/etc/sunstone-views/user.yaml @@ -138,6 +138,7 @@ tabs: - 9 # IPs #- 10 # Start Time - 11 # VNC + #- 12 # Hidden Template actions: VM.refresh: true VM.create_dialog: true diff --git a/src/sunstone/etc/sunstone-views/vcenter.yaml b/src/sunstone/etc/sunstone-views/vcenter.yaml index 70b8446020..6e7fe837b0 100644 --- a/src/sunstone/etc/sunstone-views/vcenter.yaml +++ b/src/sunstone/etc/sunstone-views/vcenter.yaml @@ -139,6 +139,7 @@ tabs: - 9 # IPs #- 10 # Start Time - 11 # VNC + #- 12 # Hidden Template actions: VM.refresh: true VM.create_dialog: true diff --git a/src/sunstone/public/js/plugins/acls-tab.js b/src/sunstone/public/js/plugins/acls-tab.js index a65b156fe1..2c68c5d33e 100644 --- a/src/sunstone/public/js/plugins/acls-tab.js +++ b/src/sunstone/public/js/plugins/acls-tab.js @@ -265,7 +265,7 @@ var acls_tab = { buttons: acl_buttons, tabClass: 'subTab', parentTab: 'system-tab', - search_input: '', + search_input: '', list_header: ' '+tr("Access Control Lists"), subheader: ' ', table: '\ diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js index ab0caccff8..626a4e9d72 100644 --- a/src/sunstone/public/js/plugins/clusters-tab.js +++ b/src/sunstone/public/js/plugins/clusters-tab.js @@ -536,7 +536,7 @@ var clusters_tab = { showOnTopMenu: false, tabClass: "subTab", parentTab: "infra-tab", - search_input: '', + search_input: '', list_header: ' '+tr("Clusters"), info_header: ' '+tr("Cluster"), subheader: '  ', diff --git a/src/sunstone/public/js/plugins/datastores-tab.js b/src/sunstone/public/js/plugins/datastores-tab.js index 5f9191b2dd..68fef0634b 100644 --- a/src/sunstone/public/js/plugins/datastores-tab.js +++ b/src/sunstone/public/js/plugins/datastores-tab.js @@ -553,7 +553,7 @@ var datastores_tab = { buttons: datastore_buttons, tabClass: "subTab", parentTab: "infra-tab", - search_input: '', + search_input: '', list_header: ' '+tr("Datastores"), info_header: ' '+tr("Datastore"), subheader: '  ', diff --git a/src/sunstone/public/js/plugins/files-tab.js b/src/sunstone/public/js/plugins/files-tab.js index fc8aaf48ae..1ec42ec9ce 100644 --- a/src/sunstone/public/js/plugins/files-tab.js +++ b/src/sunstone/public/js/plugins/files-tab.js @@ -353,7 +353,7 @@ var files_tab = { content: '
\
\
', - search_input: '', + search_input: '', list_header: ' '+tr("Files & Kernels"), info_header: ' '+tr("File"), subheader: ' '+tr("TOTAL")+' \ diff --git a/src/sunstone/public/js/plugins/groups-tab.js b/src/sunstone/public/js/plugins/groups-tab.js index d33e03a6af..39857870b6 100644 --- a/src/sunstone/public/js/plugins/groups-tab.js +++ b/src/sunstone/public/js/plugins/groups-tab.js @@ -367,7 +367,7 @@ var groups_tab = { buttons: group_buttons, tabClass: 'subTab', parentTab: 'system-tab', - search_input: '', + search_input: '', list_header: ' '+tr("Groups"), info_header: ' '+tr("Group"), subheader: '\ @@ -588,14 +588,16 @@ function updateGroupInfo(request,group){ }; Sunstone.updateInfoPanelTab("group_info_panel","group_showback_tab",showback_tab); - + } + + Sunstone.popUpInfoPanel("group_info_panel", 'groups-tab'); + + if (Config.isFeatureEnabled("showback")) { showbackGraphs( $("#group_showback","#group_info_panel"), { fixed_group: info.ID }); } - Sunstone.popUpInfoPanel("group_info_panel", 'groups-tab'); - $("#add_rp_button", $("#group_info_panel")).click(function(){ initUpdateGroupDialog(); diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 99c0398b32..0f1a05de54 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -149,6 +149,12 @@ var create_host_tmpl = \
\
\ +
\ +
\ +
\ +
\ +
\ +
\ ').appendTo($(".content", container)) if (clusters.length == 0) { $('
' + @@ -1143,7 +1417,7 @@ function setupCreateHostDialog(){ tr("No clusters found in this DataCenter") + '' + '
' + - '').appendTo(vcenter_container) + '').appendTo($(".content", container)) } else { $.each(clusters, function(id, cluster_name){ var row = $('
' + @@ -1159,211 +1433,34 @@ function setupCreateHostDialog(){ '
'+ '
'+ '
'+ - '
'+ - '
'+ - '
'+ - '
'+ - '').appendTo(vcenter_container) + '').appendTo($(".content", container)) $(".cluster_name", row).data("cluster_name", cluster_name) $(".cluster_name", row).data("datacenter_name", datacenter_name) - $(".cluster_name", row).on("change", function(){ - var templates_container = $(".vcenter_templates", $(this).closest(".vcenter_cluster")); - if ($(this).is(":checked")) { - var path = '/vcenter/' + $(this).data("datacenter_name") + '/cluster/' + $(this).data("cluster_name"); - templates_container.html(generateAdvancedSection({ - html_id: path, - title: tr("Templates"), - content: ''+ - ''+ - ''+ - '' - })) - - $('a', templates_container).trigger("click") - - $.ajax({ - url: path, - type: "GET", - data: {timeout: false}, - dataType: "json", - headers: { - "X_VCENTER_USER": $("#vcenter_user", $create_host_dialog).val(), - "X_VCENTER_PASSWORD": $("#vcenter_password", $create_host_dialog).val(), - "X_VCENTER_HOST": $("#vcenter_host", $create_host_dialog).val() - }, - success: function(response){ - $(".content", templates_container).html(""); - - $.each(response, function(id, template){ - var trow = $('
' + - '
' + - '
' + - '' + - '
'+ - '
'+ - '
' + - '
'+ - '
'+ - '
'+ - '
'+ - '
'+ - '
').appendTo($(".content", templates_container)) - - $(".template_name", trow).data("template_name", template.name) - $(".template_name", trow).data("one_template", template.one) - }); - }, - error: function(response){ - templates_container.html(""); - onError({}, OpenNebula.Error(response)); - } - }); - } else { - templates_container.html(""); - } - - var networks_container = $(".vcenter_networks", $(this).closest(".vcenter_cluster")); - if ($(this).is(":checked")) { - var path = '/vcenter/' + $(this).data("datacenter_name") + '/network/' + $(this).data("cluster_name"); - networks_container.html(generateAdvancedSection({ - html_id: path, - title: tr("Networks"), - content: ''+ - ''+ - ''+ - '' - })) - - $('a', networks_container).trigger("click") - - $.ajax({ - url: path, - type: "GET", - data: {timeout: false}, - dataType: "json", - headers: { - "X_VCENTER_USER": $("#vcenter_user", $create_host_dialog).val(), - "X_VCENTER_PASSWORD": $("#vcenter_password", $create_host_dialog).val(), - "X_VCENTER_HOST": $("#vcenter_host", $create_host_dialog).val() - }, - success: function(response){ - $(".content", networks_container).html(""); - - $.each(response, function(id, network){ - var netname = network.name.replace(" ","_"); - - var trow = $('
' + - '
' + - '
' + - '
' + - '' + - '
'+ - '
'+ - '' + - '
'+ - '
'+ - '' + - '
'+ - '
' + - '
'+ - ''+ - '
'+ - '
'+ - '
'+ - '
'+ - '
' + - '
'+ - '
'+ - '
'+ - '
'+ - '
'+ - '
').appendTo($(".content", networks_container)) - - - $('.type_select').on("change",function(){ - var network_context = $(this).closest(".vcenter_network"); - var type = $(this).val(); - - var net_form_str = '' - - switch(type) { - case 'ETHER': - net_form_str = - '
'+ - ''+ - '
'; - break; - case 'IP4': - net_form_str = - '
'+ - ''+ - '
'+ - '
'+ - ''+ - '
'; - break; - case 'IP6': - net_form_str = - '
'+ - ''+ - '
'+ - '
'+ - ''+ - '
'+ - '
'+ - ''+ - '
'; - break; - } - - $('.net_options', network_context).html(net_form_str); - }); - - $(".network_name", trow).data("network_name", netname) - $(".network_name", trow).data("one_network", network.one) - }); - }, - error: function(response){ - networks_container.html(""); - onError({}, OpenNebula.Error(response)); - } - }); - } else { - networks_container.html(""); - } - }) }); } }); + + var templates_container = $(".vcenter_templates", $create_host_dialog); + var networks_container = $(".vcenter_networks", $create_host_dialog); + + var vcenter_user = $("#vcenter_user", $create_host_dialog).val(); + var vcenter_password = $("#vcenter_password", $create_host_dialog).val(); + var vcenter_host = $("#vcenter_host", $create_host_dialog).val(); + + fillVCenterTemplates({ + container: templates_container, + vcenter_user: vcenter_user, + vcenter_password: vcenter_password, + vcenter_host: vcenter_host + }); + + fillVCenterNetworks({ + container: networks_container, + vcenter_user: vcenter_user, + vcenter_password: vcenter_password, + vcenter_host: vcenter_host + }); }, error: function(response){ $(".vcenter_clusters", $create_host_dialog).html('') @@ -1421,145 +1518,6 @@ function setupCreateHostDialog(){ Sunstone.runAction("Host.update_template", response.HOST.ID, template_raw); addHostElement(request, response); - - $.each($(".template_name:checked", cluster_context), function(){ - var template_context = $(this).closest(".vcenter_template"); - - $(".vcenter_template_result:not(.success)", template_context).html( - ''+ - ''+ - ''+ - ''); - - var template_json = { - "vmtemplate": { - "template_raw": $(this).data("one_template") - } - }; - - OpenNebula.Template.create({ - timeout: true, - data: template_json, - success: function(request, response) { - OpenNebula.Helper.clear_cache("VMTEMPLATE"); - $(".vcenter_template_result", template_context).addClass("success").html( - ''+ - ''+ - ''+ - ''); - - $(".vcenter_template_response", template_context).html('

'+ - tr("Template created successfully")+' ID:'+response.VMTEMPLATE.ID+ - '

'); - }, - error: function (request, error_json){ - $(".vcenter_template_result", template_context).html(''+ - ''+ - ''+ - ''); - - $(".vcenter_template_response", template_context).html('

'+ - (error_json.error.message || tr("Cannot contact server: is it running and reachable?"))+ - '

'); - } - }); - }) - - $.each($(".network_name:checked", cluster_context), function(){ - var network_context = $(this).closest(".vcenter_network"); - - $(".vcenter_network_result:not(.success)", network_context).html( - ''+ - ''+ - ''+ - ''); - - var network_size = $(".netsize", network_context).val(); - var network_tmpl = $(this).data("one_network"); - var netname = $(this).data("network_name"); - var type = $('.type_select', network_context).val(); - - var ar_array = []; - ar_array.push("TYPE=" + type); - ar_array.push("SIZE=" + network_size); - - switch(type) { - case 'ETHER': - var mac = $('.eth_mac_net', network_context).val(); - - if (mac){ - ar_array.push("MAC=" + mac); - } - - break; - case 'IP4': - var mac = $('.four_mac_net', network_context).val(); - var ip = $('.four_ip_net', network_context).val(); - - if (mac){ - ar_array.push("MAC=" + mac); - } - if (ip) { - ar_array.push("IP=" + ip); - } - - break; - case 'IP6': - var mac = $('.six_mac_net', network_context).val(); - var gp = $('.six_global_net', network_context).val(); - var ula = $('.six_mac_net', network_context).val(); - - if (mac){ - ar_array.push("MAC=" + mac); - } - if (gp) { - ar_array.push("GLOBAL_PREFIX=" + gp); - } - if (ula){ - ar_array.push("ULA_PREFIX=" + ula); - } - - break; - } - - network_tmpl += "\nAR=[" - network_tmpl += ar_array.join(",\n") - network_tmpl += "]" - - var vnet_json = { - "vnet": { - "vnet_raw": network_tmpl - } - }; - - OpenNebula.Network.create({ - timeout: true, - data: vnet_json, - success: function(request, response) { - OpenNebula.Helper.clear_cache("VNET"); - $(".vcenter_network_result", network_context).addClass("success").html( - ''+ - ''+ - ''+ - ''); - - $(".vcenter_network_response", network_context).html('

'+ - tr("Virtual Network created successfully")+' ID:'+response.VNET.ID+ - '

'); - }, - error: function (request, error_json){ - $(".vcenter_network_result", network_context).html(''+ - ''+ - ''+ - ''); - - $(".vcenter_network_response", network_context).html('

'+ - (error_json.error.message || tr("Cannot contact server: is it running and reachable?"))+ - '

'); - } - }); - }) - }, error: function (request, error_json){ $(".vcenter_host_result", $create_host_dialog).html(''+ @@ -1574,6 +1532,144 @@ function setupCreateHostDialog(){ }); }) + $.each($(".template_name:checked", $create_host_dialog), function(){ + var template_context = $(this).closest(".vcenter_template"); + + $(".vcenter_template_result:not(.success)", template_context).html( + ''+ + ''+ + ''+ + ''); + + var template_json = { + "vmtemplate": { + "template_raw": $(this).data("one_template") + } + }; + + OpenNebula.Template.create({ + timeout: true, + data: template_json, + success: function(request, response) { + OpenNebula.Helper.clear_cache("VMTEMPLATE"); + $(".vcenter_template_result", template_context).addClass("success").html( + ''+ + ''+ + ''+ + ''); + + $(".vcenter_template_response", template_context).html('

'+ + tr("Template created successfully")+' ID:'+response.VMTEMPLATE.ID+ + '

'); + }, + error: function (request, error_json){ + $(".vcenter_template_result", template_context).html(''+ + ''+ + ''+ + ''); + + $(".vcenter_template_response", template_context).html('

'+ + (error_json.error.message || tr("Cannot contact server: is it running and reachable?"))+ + '

'); + } + }); + }) + + $.each($(".network_name:checked", $create_host_dialog), function(){ + var network_context = $(this).closest(".vcenter_network"); + + $(".vcenter_network_result:not(.success)", network_context).html( + ''+ + ''+ + ''+ + ''); + + var network_size = $(".netsize", network_context).val(); + var network_tmpl = $(this).data("one_network"); + var netname = $(this).data("network_name"); + var type = $('.type_select', network_context).val(); + + var ar_array = []; + ar_array.push("TYPE=" + type); + ar_array.push("SIZE=" + network_size); + + switch(type) { + case 'ETHER': + var mac = $('.eth_mac_net', network_context).val(); + + if (mac){ + ar_array.push("MAC=" + mac); + } + + break; + case 'IP4': + var mac = $('.four_mac_net', network_context).val(); + var ip = $('.four_ip_net', network_context).val(); + + if (mac){ + ar_array.push("MAC=" + mac); + } + if (ip) { + ar_array.push("IP=" + ip); + } + + break; + case 'IP6': + var mac = $('.six_mac_net', network_context).val(); + var gp = $('.six_global_net', network_context).val(); + var ula = $('.six_mac_net', network_context).val(); + + if (mac){ + ar_array.push("MAC=" + mac); + } + if (gp) { + ar_array.push("GLOBAL_PREFIX=" + gp); + } + if (ula){ + ar_array.push("ULA_PREFIX=" + ula); + } + + break; + } + + network_tmpl += "\nAR=[" + network_tmpl += ar_array.join(",\n") + network_tmpl += "]" + + var vnet_json = { + "vnet": { + "vnet_raw": network_tmpl + } + }; + + OpenNebula.Network.create({ + timeout: true, + data: vnet_json, + success: function(request, response) { + OpenNebula.Helper.clear_cache("VNET"); + $(".vcenter_network_result", network_context).addClass("success").html( + ''+ + ''+ + ''+ + ''); + + $(".vcenter_network_response", network_context).html('

'+ + tr("Virtual Network created successfully")+' ID:'+response.VNET.ID+ + '

'); + }, + error: function (request, error_json){ + $(".vcenter_network_result", network_context).html(''+ + ''+ + ''+ + ''); + + $(".vcenter_network_response", network_context).html('

'+ + (error_json.error.message || tr("Cannot contact server: is it running and reachable?"))+ + '

'); + } + }); + }); + return false }); @@ -1603,6 +1699,14 @@ function setupCreateHostDialog(){ $('input[name="custom_vnm_mad"]').parent().hide(); }); + $('#create_host_form').on("keyup keypress", function(e) { + var code = e.keyCode || e.which; + if (code == 13) { + e.preventDefault(); + return false; + } + }); + //Handle the form submission $('#create_host_form',$create_host_dialog).submit(function(){ var name = $('#name',this).val(); @@ -1638,20 +1742,25 @@ function setupCreateHostDialog(){ }); } +function resetCreateHostDialog(){ + $create_host_dialog.empty(); + setupCreateHostDialog(); + + $create_host_dialog = $('div#create_host_dialog'); + + var cluster_id = $('#host_cluster_id .resource_list_select', $create_host_dialog).val(); + if (!cluster_id) cluster_id = "-1"; + + insertSelectOptions('#host_cluster_id', $create_host_dialog, "Cluster", cluster_id, false); + $("input#name", $create_host_dialog).focus(); + return false; +} + //Open creation dialogs function popUpCreateHostDialog(){ - $create_host_dialog.foundation('reveal', 'close'); - $create_host_dialog.empty(); - setupCreateHostDialog(); - - var cluster_id = $('#host_cluster_id .resource_list_select',$('div#create_host_dialog')).val(); - if (!cluster_id) cluster_id = "-1"; - - insertSelectOptions('#host_cluster_id',$('div#create_host_dialog'), "Cluster", cluster_id, false); - - $("#create_host_dialog").foundation('reveal', 'open'); - $("input#name",$("#create_host_dialog")).focus(); - return false; + resetCreateHostDialog(); + $create_host_dialog.foundation('reveal', 'open'); + return false; } // Call back when individual host history monitoring fails diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index 6ca4a6e47c..b235294c4a 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -498,7 +498,7 @@ var images_tab = { content: '
\
\
', - search_input: '', + search_input: '', list_header: ' '+tr("Images"), info_header: ' '+tr("Image"), subheader: ' '+tr("TOTAL")+' \ diff --git a/src/sunstone/public/js/plugins/marketplace-tab.js b/src/sunstone/public/js/plugins/marketplace-tab.js index df0114b5b4..4d191f5055 100644 --- a/src/sunstone/public/js/plugins/marketplace-tab.js +++ b/src/sunstone/public/js/plugins/marketplace-tab.js @@ -357,7 +357,7 @@ var marketplace_import_dialog = var marketplace_tab = { title: ' ' + tr("Marketplace"), buttons: market_buttons, - search_input: '', + search_input: '', list_header: ' '+tr("OpenNebula Marketplace"), info_header: ' '+tr("Appliance"), subheader: '  ', diff --git a/src/sunstone/public/js/plugins/oneflow-services.js b/src/sunstone/public/js/plugins/oneflow-services.js index f2fba4ac39..b95f696c7f 100644 --- a/src/sunstone/public/js/plugins/oneflow-services.js +++ b/src/sunstone/public/js/plugins/oneflow-services.js @@ -819,7 +819,7 @@ var services_tab = { buttons: service_buttons, tabClass: 'subTab', parentTab: 'oneflow-dashboard', - search_input: '', + search_input: '', list_header: ' '+tr("OneFlow - Services"), info_header: ' '+tr("OneFlow - Service"), subheader: '  ', diff --git a/src/sunstone/public/js/plugins/oneflow-templates.js b/src/sunstone/public/js/plugins/oneflow-templates.js index a4b1a90311..8773d48cc1 100644 --- a/src/sunstone/public/js/plugins/oneflow-templates.js +++ b/src/sunstone/public/js/plugins/oneflow-templates.js @@ -621,7 +621,7 @@ var service_templates_tab = { buttons: service_template_buttons, tabClass: 'subTab', parentTab: 'oneflow-dashboard', - search_input: '', + search_input: '', list_header: ' '+tr("OneFlow - Templates"), info_header: ' '+tr("OneFlow - Template"), subheader: '  ', diff --git a/src/sunstone/public/js/plugins/provision-tab.js b/src/sunstone/public/js/plugins/provision-tab.js index 4bbdd07e40..6670441c57 100644 --- a/src/sunstone/public/js/plugins/provision-tab.js +++ b/src/sunstone/public/js/plugins/provision-tab.js @@ -2112,6 +2112,8 @@ function generate_custom_attrs(context, custom_attrs) { ''+ ''); }) + } else { + context.html(""); } } @@ -2317,7 +2319,7 @@ function generate_provision_instance_type_accordion(context, capacity) { $(".cost_value").data("MEMORY_COST", capacity.MEMORY_COST); } - $(".cost_value").html(cost); + $(".cost_value").html(cost.toFixed(2)); } else { $(".provision_create_template_cost_div").hide(); } @@ -2426,7 +2428,7 @@ function generate_provision_instance_type_accordion(context, capacity) { cost += $(this).attr("memory") * $(".cost_value").data("MEMORY_COST") } - $(".cost_value").html(cost); + $(".cost_value").html(cost.toFixed(2)); } $('.accordion a', context).first().trigger("click"); @@ -3706,6 +3708,11 @@ function setup_info_vm(context) { break; } + if (!enableVnc(data) && !enableSPICE(data)) { + $(".provision_vnc_button", context).hide(); + $(".provision_vnc_button_disabled", context).hide(); + } + $(".provision_info_vm", context).attr("vm_id", data.ID); $(".provision_info_vm", context).data("vm", data); @@ -4306,7 +4313,7 @@ function setup_provision_vms_list(context, opts) { if ($(this).val() != "-2"){ provision_vms_datatable.fnFilter("^" + $(this).val() + "$", 2, true, false); } else { - provision_vms_datatable.fnFilterClear(); + provision_vms_datatable.fnFilter("", 2); } }) @@ -4460,7 +4467,7 @@ function setup_provision_templates_list(context, opts) { if ($(this).val() != "-2"){ provision_templates_datatable.fnFilter("^" + $(this).val() + "$", 3, true, false); } else { - provision_templates_datatable.fnFilterClear(); + provision_templates_datatable.fnFilter("", 3); } }) @@ -5176,7 +5183,7 @@ function setup_provision_flows_list(context, opts){ if ($(this).val() != "-2"){ provision_flows_datatable.fnFilter("^" + $(this).val() + "$", 2, true, false); } else { - provision_flows_datatable.fnFilterClear(); + provision_flows_datatable.fnFilter("", 2); } }) @@ -6328,16 +6335,21 @@ $(document).ready(function(){ var template_id = $(".tabs-content .content.active .selected", context).attr("opennebula_id"); var nics = []; + var nic; $(".selected_network", context).each(function(){ - var nic; if ($(this).attr("template_nic")) { nic = JSON.parse($(this).attr("template_nic")) - } else { + } else if ($(this).attr("opennebula_id")) { nic = { 'network_id': $(this).attr("opennebula_id") } + } else { + nic = undefined; + } + + if (nic) { + nics.push(nic); } - nics.push(nic); }); var instance_type = $(".provision_instance_types_ul .selected", context); diff --git a/src/sunstone/public/js/plugins/secgroups-tab.js b/src/sunstone/public/js/plugins/secgroups-tab.js index 5b32c481dd..8cfcb2ed0f 100644 --- a/src/sunstone/public/js/plugins/secgroups-tab.js +++ b/src/sunstone/public/js/plugins/secgroups-tab.js @@ -727,7 +727,7 @@ var security_groups_tab = { buttons: security_group_buttons, tabClass: "subTab", parentTab: "infra-tab", - search_input: '', + search_input: '', list_header: ' '+tr("Security Groups"), info_header: ' '+tr("Security Group"), subheader: '  ', diff --git a/src/sunstone/public/js/plugins/support-tab.js b/src/sunstone/public/js/plugins/support-tab.js index a720cbc655..857acb8393 100644 --- a/src/sunstone/public/js/plugins/support-tab.js +++ b/src/sunstone/public/js/plugins/support-tab.js @@ -242,7 +242,7 @@ var support_tab = { \
', buttons: support_buttons, - search_input: '', + search_input: '', list_header: ' Commercial Support Requests', info_header: ' Commercial Support Request', subheader: '
'+ diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index 4488a5045a..26ab000f07 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -259,7 +259,7 @@ if (Config.isTemplateCreationTabEnabled('os_booting')){ '' + '
' + '
'+ - ''+ + ''+ '
'+ ''+ '
'+ @@ -326,7 +326,7 @@ if (Config.isTemplateCreationTabEnabled('os_booting')){ '' + '
' + '
'+ - ''+ + ''+ '
'+ ''+ '
'+ @@ -617,7 +617,7 @@ if (Config.isTemplateCreationTabEnabled('context')){ '' + '
' + '
'+ - ''+ + ''+ '
'+ ''+ '
'+ @@ -766,7 +766,7 @@ if (Config.isTemplateCreationTabEnabled('scheduling')){ '' + '
' + '
'+ - ''+ + ''+ '
'+ ''+ '
'+ @@ -807,7 +807,7 @@ if (Config.isTemplateCreationTabEnabled('scheduling')){ '' + '
' + '
'+ - ''+ + ''+ '
'+ ''+ '
'+ @@ -1652,7 +1652,7 @@ var templates_tab = { buttons: template_buttons, tabClass: 'subTab', parentTab: 'vresources-tab', - search_input: '', + search_input: '', list_header: ' '+tr("Templates"), info_header: ' '+tr("Template"), subheader: ' ', diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index 0cca9bf325..8b95a8085b 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -399,7 +399,7 @@ var users_tab = { buttons: user_buttons, tabClass: 'subTab', parentTab: 'system-tab', - search_input: ' ', + search_input: ' ', list_header: ' '+tr("Users"), info_header: ' '+tr("User"), subheader: '\ @@ -464,17 +464,7 @@ function userElementArray(user_json){ } // Build hidden user template - var hidden_template = ""; - for (var key in user.TEMPLATE){ - switch (key){ - // Don't copy unnecesary keys - case "SSH_PUBLIC_KEY": - case "TOKEN_PASSWORD": - break; - default: - hidden_template = hidden_template + key + "=" + user.TEMPLATE[key] + "\n"; - } - } + var hidden_template = convert_template_to_string(user); return [ '', @@ -635,13 +625,16 @@ function updateUserInfo(request,user){ }; Sunstone.updateInfoPanelTab("user_info_panel","user_showback_tab",showback_tab); - + } + + //Sunstone.updateInfoPanelTab("user_info_panel","user_acct_tab",acct_tab); + Sunstone.popUpInfoPanel("user_info_panel", 'users-tab'); + + if (Config.isFeatureEnabled("showback")) { showbackGraphs( $("#user_showback","#user_info_panel"), { fixed_user: info.ID }); } - //Sunstone.updateInfoPanelTab("user_info_panel","user_acct_tab",acct_tab); - Sunstone.popUpInfoPanel("user_info_panel", 'users-tab'); accountingGraphs( $("#user_accounting","#user_info_panel"), @@ -883,7 +876,7 @@ $(document).ready(function(){ }); $('#user_search').keyup(function(){ - dataTable_users.fnFilter( $(this).val() ); + dataTable_users.fnFilter( $(this).val(), null, true, false ); }) dataTable_users.on('draw', function(){ diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index 969338d39e..b5958aeae3 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -942,7 +942,7 @@ var vms_tab = { buttons: vm_buttons, tabClass: 'subTab', parentTab: 'vresources-tab', - search_input: '', + search_input: '', list_header: ' '+tr("Virtual Machines"), info_header: ' '+tr("VM"), subheader: ' '+tr("TOTAL")+' \ @@ -965,6 +965,7 @@ var vms_tab = { '+tr("IPs")+'\ '+tr("Start Time")+'\ '+tr("")+'\ + '+tr("Hidden Template")+'\ \ \ \ @@ -1032,6 +1033,8 @@ function vMachineElementArray(vm_json){ state = OpenNebula.Helper.resource_state("vm_lcm",vm.LCM_STATE); }; + // Build hidden user template + var hidden_template = convert_template_to_string(vm); return [ '', @@ -1045,7 +1048,8 @@ function vMachineElementArray(vm_json){ hostname, ip_str(vm), str_start_time(vm), - vncIcon(vm) + vncIcon(vm), + hidden_template ]; }; @@ -3388,7 +3392,7 @@ $(document).ready(function(){ }); $('#vms_search').keyup(function(){ - dataTable_vMachines.fnFilter( $(this).val() ); + dataTable_vMachines.fnFilter( $(this).val(), null, true, false ); }) dataTable_vMachines.on('draw', function(){ diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 3d6973d7ed..1032eee2a9 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -22,7 +22,7 @@ var create_vnet_wizard_html =
\
\

'+tr("General")+'
\ -

'+tr("Configuration")+'
\ +

'+tr("Conf")+'
\

'+tr("Addresses")+'
\

'+tr("Security")+'
\

'+tr("Context")+'
\ @@ -619,7 +619,7 @@ var vnets_tab = { buttons: vnet_buttons, tabClass: "subTab", parentTab: "infra-tab", - search_input: '', + search_input: '', list_header: ' '+tr("Virtual Networks"), info_header: ' '+tr("Virtual Network"), subheader: ' '+tr("TOTAL")+' \ diff --git a/src/sunstone/public/js/plugins/zones-tab.js b/src/sunstone/public/js/plugins/zones-tab.js index 60a05130a6..3d14acc26a 100644 --- a/src/sunstone/public/js/plugins/zones-tab.js +++ b/src/sunstone/public/js/plugins/zones-tab.js @@ -220,7 +220,7 @@ var zones_tab = { buttons: zone_buttons, tabClass: "subTab", parentTab: "infra-tab", - search_input: '', + search_input: '', list_header: ' '+tr("Zones"), info_header: ' '+tr("Zone"), subheader: '  ', diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index 945f7e14aa..0d74e6b8fb 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -4800,10 +4800,6 @@ function time_UTC(time){ // fixed_group_by "user", "group", "vm". set a fixed group-by selector function showbackGraphs(div, opt){ - if(div.html() != ""){ - return false; - } - div.html( '
\
\ @@ -5406,10 +5402,16 @@ function fillAccounting(div, req, response, no_table) { var start = new Date(options.start_time * 1000); start.setUTCHours(0,0,0,0); - var end = new Date(); + var end; + var now = new Date(); - if(options.end_time != undefined && options.end_time != -1){ - var end = new Date(options.end_time * 1000) + if (options.end_time != undefined && options.end_time != -1) { + end = new Date(options.end_time * 1000) + if (end > now) { + end = now; + } + } else { + end = now; } // granularity of 1 day @@ -5426,6 +5428,10 @@ function fillAccounting(div, req, response, no_table) { tmp_time.setUTCDate( tmp_time.getUTCDate() + 1 ); } + if (tmp_time > now) { + times.push(now.getTime()); + } + //-------------------------------------------------------------------------- // Flot options //-------------------------------------------------------------------------- @@ -7187,7 +7193,7 @@ function generateResourceTableSelect(context_id, columns, options){ \
\
\ - \ + \
\
\
\ diff --git a/src/sunstone/routes/support.rb b/src/sunstone/routes/support.rb index e8d37a143c..8836f3e912 100644 --- a/src/sunstone/routes/support.rb +++ b/src/sunstone/routes/support.rb @@ -55,7 +55,9 @@ helpers do # config.adapter = :patron # Merged with the default client options hash - # config.client_options = { :ssl => false } + if ENV['http_proxy'] + config.client_options = { :proxy => ENV['http_proxy'] } + end # When getting the error 'hostname does not match the server certificate' # use the API at https://yoursubdomain.zendesk.com/api/v2 diff --git a/src/sunstone/routes/vcenter.rb b/src/sunstone/routes/vcenter.rb index 2d70844863..5718dbf2b2 100644 --- a/src/sunstone/routes/vcenter.rb +++ b/src/sunstone/routes/vcenter.rb @@ -67,20 +67,19 @@ get '/vcenter' do end end -get '/vcenter/:datacenter/cluster/:name' do +get '/vcenter/templates' do begin - rs = vcenter_client.vm_templates - - templates = rs[params[:datacenter]] + templates = vcenter_client.vm_templates( + $cloud_auth.client(session[:user], session[:active_zone_endpoint])) if templates.nil? - msg = "Datacenter " + params[:datacenter] + "not found" + msg = "No datacenter found" logger.error("[vCenter] " + msg) error = Error.new(msg) error 404, error.to_json end - ctemplates = templates.select{|t| t[:host] == params[:name]} - [200, ctemplates.to_json] + #ctemplates = templates.select{|t| t[:host] == params[:name]} + [200, templates.to_json] rescue Exception => e logger.error("[vCenter] " + e.message) error = Error.new(e.message) @@ -88,13 +87,12 @@ get '/vcenter/:datacenter/cluster/:name' do end end -get '/vcenter/:datacenter/network/:name' do +get '/vcenter/networks' do begin - rs = vcenter_client.vcenter_networks - - networks = rs[params[:datacenter]] + networks = vcenter_client.vcenter_networks( + $cloud_auth.client(session[:user], session[:active_zone_endpoint])) if networks.nil? - msg = "Datacenter " + params[:datacenter] + "not found" + msg = "No datacenter found" logger.error("[vCenter] " + msg) error = Error.new(msg) error 404, error.to_json diff --git a/src/vmm_mad/remotes/vcenter/vcenter_driver.rb b/src/vmm_mad/remotes/vcenter/vcenter_driver.rb index b507d2bb98..1eebe0cbc1 100644 --- a/src/vmm_mad/remotes/vcenter/vcenter_driver.rb +++ b/src/vmm_mad/remotes/vcenter/vcenter_driver.rb @@ -204,12 +204,18 @@ class VIClient ######################################################################## # Builds a hash with the Datacenter / VM Templates for this VCenter + # @param one_client [OpenNebula::Client] Use this client instead of @one # @return [Hash] in the form # { dc_name [String] => } ######################################################################## - def vm_templates + def vm_templates(one_client=nil) vm_templates = {} + tpool = OpenNebula::TemplatePool.new( + (one_client||@one), OpenNebula::Pool::INFO_ALL) + rc = tpool.info + # TODO check error + datacenters = get_entities(@root, 'Datacenter') datacenters.each { |dc| @@ -222,12 +228,16 @@ class VIClient tmp.each { |t| vi_tmp = VCenterVm.new(self, t) - one_tmp << { - :name => vi_tmp.vm.name, - :uuid => vi_tmp.vm.config.uuid, - :host => vi_tmp.vm.runtime.host.parent.name, - :one => vi_tmp.to_one - } + if !tpool["VMTEMPLATE/TEMPLATE/PUBLIC_CLOUD[\ + TYPE=\"vcenter\" \ + and VM_TEMPLATE=\"#{vi_tmp.vm.config.uuid}\"]"] + one_tmp << { + :name => vi_tmp.vm.name, + :uuid => vi_tmp.vm.config.uuid, + :host => vi_tmp.vm.runtime.host.parent.name, + :one => vi_tmp.to_one + } + end } vm_templates[dc.name] = one_tmp @@ -239,12 +249,18 @@ class VIClient ######################################################################## # Builds a hash with the Datacenter / CCR (Distributed)Networks # for this VCenter + # @param one_client [OpenNebula::Client] Use this client instead of @one # @return [Hash] in the form # { dc_name [String] => Networks [Array] } ######################################################################## - def vcenter_networks + def vcenter_networks(one_client=nil) vcenter_networks = {} + vnpool = OpenNebula::VirtualNetworkPool.new( + (one_client||@one), OpenNebula::Pool::INFO_ALL) + rc = vnpool.info + # TODO check error + # datacenters = get_entities(@root, 'Datacenter') datacenters.each { |dc| @@ -252,51 +268,57 @@ class VIClient one_nets = [] networks.each { |n| - one_nets << { - :name => n.name, - :bridge => n.name, - :type => "Port Group", - :one => "NAME = \"#{n[:name]}\"\n" \ - "BRIDGE = \"#{n[:name]}\"\n" \ - "VCENTER_TYPE = \"Port Group\"" - } + if !vnpool["VNET[BRIDGE=\"#{n[:name]}\"]/\ + TEMPLATE[VCENTER_TYPE=\"Port Group\"]"] + one_nets << { + :name => n.name, + :bridge => n.name, + :type => "Port Group", + :one => "NAME = \"#{n[:name]}\"\n" \ + "BRIDGE = \"#{n[:name]}\"\n" \ + "VCENTER_TYPE = \"Port Group\"" + } + end } networks = get_entities(dc.networkFolder, 'DistributedVirtualPortgroup' ) networks.each { |n| - vnet_template = "NAME = \"#{n[:name]}\"\n" \ - "BRIDGE = \"#{n[:name]}\"\n" \ - "VCENTER_TYPE = \"Distributed Port Group\"" + if !vnpool["VNET[BRIDGE=\"#{n[:name]}\"]/\ + TEMPLATE[VCENTER_TYPE=\"Distributed Port Group\"]"] + vnet_template = "NAME = \"#{n[:name]}\"\n" \ + "BRIDGE = \"#{n[:name]}\"\n" \ + "VCENTER_TYPE = \"Distributed Port Group\"" - vlan = n.config.defaultPortConfig.vlan.vlanId - vlan_str = "" + vlan = n.config.defaultPortConfig.vlan.vlanId + vlan_str = "" - if vlan != 0 - if vlan.is_a? Array - vlan.each{|v| - vlan_str += v.start.to_s + ".." + v.end.to_s + "," - } - vlan_str.chop! - else - vlan_str = vlan.to_s + if vlan != 0 + if vlan.is_a? Array + vlan.each{|v| + vlan_str += v.start.to_s + ".." + v.end.to_s + "," + } + vlan_str.chop! + else + vlan_str = vlan.to_s + end end + + if !vlan_str.empty? + vnet_template << "VLAN=\"YES\"\n" \ + "VLAN_ID=#{vlan_str}\n" + end + + one_net = {:name => n.name, + :bridge => n.name, + :type => "Distributed Port Group", + :one => vnet_template} + + one_net[:vlan] = vlan_str if !vlan_str.empty? + + one_nets << one_net end - - if !vlan_str.empty? - vnet_template << "VLAN=\"YES\"\n" \ - "VLAN_ID=#{vlan_str}\n" - end - - one_net = {:name => n.name, - :bridge => n.name, - :type => "Distributed Port Group", - :one => vnet_template} - - one_net[:vlan] = vlan_str if !vlan_str.empty? - - one_nets << one_net } vcenter_networks[dc.name] = one_nets diff --git a/src/vnm_mad/remotes/802.1Q/pre b/src/vnm_mad/remotes/802.1Q/pre index 656fca6415..1dd5d1d12d 100755 --- a/src/vnm_mad/remotes/802.1Q/pre +++ b/src/vnm_mad/remotes/802.1Q/pre @@ -19,7 +19,7 @@ $: << File.dirname(__FILE__) $: << File.join(File.dirname(__FILE__), "..") -require 'vlan_driver' +require 'vlan_tag_driver' -hm = VLANDriver.from_base64(ARGV[0]) +hm = VLANTagDriver.from_base64(ARGV[0]) exit hm.activate diff --git a/src/vnm_mad/remotes/802.1Q/vlan_driver.rb b/src/vnm_mad/remotes/802.1Q/vlan_driver.rb deleted file mode 100644 index f3dcf5dabc..0000000000 --- a/src/vnm_mad/remotes/802.1Q/vlan_driver.rb +++ /dev/null @@ -1,130 +0,0 @@ -# -------------------------------------------------------------------------- # -# 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 'vnmmad' - -################################################################################ -# This driver tag VM traffic with a VLAN_ID using 802.1Q protocol. Features: -# - Creates a bridge and bind phisycal device if not present -# - Creates a tagged interface for the VM dev.vlan_id -# -# Once activated the VM will be attached to this bridge -################################################################################ -class VLANDriver < VNMMAD::VNMDriver - - # DRIVER name and XPATH for relevant NICs - DRIVER = "802.1Q" - XPATH_FILTER = "TEMPLATE/NIC[VLAN='YES']" - - ############################################################################ - # Creatges the driver device operations are not locked - ############################################################################ - def initialize(vm, deploy_id = nil, hypervisor = nil) - super(vm, XPATH_FILTER, deploy_id, hypervisor) - @locking = false - - lock - @bridges = get_interfaces - unlock - end - - ############################################################################ - # Activate the driver and creates bridges and tags devices as needed. - ############################################################################ - def activate - lock - - vm_id = @vm['ID'] - - process do |nic| - bridge = nic[:bridge] - dev = nic[:phydev] - - if dev - if nic[:vlan_id] - vlan = nic[:vlan_id] - else - vlan = CONF[:start_vlan] + nic[:network_id].to_i - end - - if !bridge_exists? bridge - create_bridge bridge - ifup bridge - end - - if !device_exists?(dev, vlan) - create_dev_vlan(dev, vlan) - ifup(dev, vlan) - end - - if !attached_bridge_dev?(bridge, dev, vlan) - attach_brigde_dev(bridge, dev, vlan) - end - end - end - - unlock - - return 0 - end - - ############################################################################ - # Private interface, methods to manage bridges and VLAN tags through the - # brctl and ip commands - ############################################################################ - private - - def bridge_exists?(bridge) - @bridges.keys.include? bridge - end - - def create_bridge(bridge) - OpenNebula.exec_and_log("#{command(:brctl)} addbr #{bridge}") - @bridges[bridge] = Array.new - end - - def device_exists?(dev, vlan=nil) - dev = "#{dev}.#{vlan}" if vlan - `#{command(:ip)} link show #{dev}` - $?.exitstatus == 0 - end - - def create_dev_vlan(dev, vlan) - cmd = "#{command(:ip)} link add link #{dev}" - cmd << " name #{dev}.#{vlan} type vlan id #{vlan}" - - OpenNebula.exec_and_log(cmd) - end - - def attached_bridge_dev?(bridge, dev, vlan=nil) - return false if !bridge_exists? bridge - - dev = "#{dev}.#{vlan}" if vlan - @bridges[bridge].include? dev - end - - def attach_brigde_dev(bridge, dev, vlan=nil) - dev = "#{dev}.#{vlan}" if vlan - - OpenNebula.exec_and_log("#{command(:brctl)} addif #{bridge} #{dev}") - @bridges[bridge] << dev - end - - def ifup(dev, vlan=nil) - dev = "#{dev}.#{vlan}" if vlan - OpenNebula.exec_and_log("#{command(:ip)} link set #{dev} up") - end -end diff --git a/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb b/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb new file mode 100644 index 0000000000..bc2f6c0ce1 --- /dev/null +++ b/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb @@ -0,0 +1,51 @@ +# -------------------------------------------------------------------------- # +# 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 'vnmmad' + +################################################################################ +# This driver tag VM traffic with a VLAN_ID using 802.1Q protocol. Features: +# - Creates a bridge and bind phisycal device if not present +# - Creates a tagged interface for the VM dev.vlan_id +# +# Once activated the VM will be attached to this bridge +################################################################################ +class VLANTagDriver < VNMMAD::VLANDriver + + # DRIVER name and XPATH for relevant NICs + DRIVER = "802.1Q" + XPATH_FILTER = "TEMPLATE/NIC[VLAN='YES']" + + ############################################################################ + # Creatges the driver device operations are not locked + ############################################################################ + def initialize(vm, deploy_id = nil, hypervisor = nil) + @locking = false + + super(vm, XPATH_FILTER, deploy_id, hypervisor) + end + + ############################################################################ + # This function creates and activate a VLAN device + ############################################################################ + def create_vlan_dev(options) + OpenNebula.exec_and_log("#{command(:ip)} link add link"\ + " #{options[:phydev]} name #{options[:vlan_dev]} type vlan id"\ + " #{options[:vlan_id]}") + + OpenNebula.exec_and_log("#{command(:ip)} link set #{options[:vlan_dev]} up") + end +end diff --git a/src/vnm_mad/remotes/OpenNebulaNetwork.conf b/src/vnm_mad/remotes/OpenNebulaNetwork.conf index 8ab0d99ad4..f622b63d87 100644 --- a/src/vnm_mad/remotes/OpenNebulaNetwork.conf +++ b/src/vnm_mad/remotes/OpenNebulaNetwork.conf @@ -27,3 +27,10 @@ # Enable ARP Cache Poisoning Prevention Rules :arp_cache_poisoning: true + +################################################################################ +# VXLAN Options +################################################################################ + +# Base multicast address for each VLAN. The mc address is :vxlan_mc + :vlan_id +:vxlan_mc: 239.0.0.0 diff --git a/src/vnm_mad/remotes/lib/vlan.rb b/src/vnm_mad/remotes/lib/vlan.rb new file mode 100644 index 0000000000..0a2f20e951 --- /dev/null +++ b/src/vnm_mad/remotes/lib/vlan.rb @@ -0,0 +1,135 @@ +# -------------------------------------------------------------------------- # +# 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. # +#--------------------------------------------------------------------------- # + +module VNMMAD + + ############################################################################ + # Module to use as mixin for implementing VLAN drivers based on special + # link devices though the Linux kernel features and bridges. It provides + # common functionality to handle bridges + ############################################################################ + class VLANDriver < VNMMAD::VNMDriver + + def initialize(vm_tpl, xpath_filter, deploy_id = nil, hypervisor = nil) + super(vm_tpl, xpath_filter, deploy_id, hypervisor) + + lock + @bridges = get_bridges + unlock + end + + # Activate the driver and creates bridges and tags devices as needed. + def activate + lock + + options = Hash.new + + process do |nic| + + options.clear + + options[:bridge] = nic[:bridge] + options[:phydev] = nic[:phydev] + options[:vlan_id] = nic[:vlan_id] + options[:network_id] = nic[:network_id] + + return if options[:phydev].nil? + + set_up_vlan(options) + end + + unlock + + return 0 + end + + # Set ups the VLAN for the VMs. + # @param options [Hash] including + # - :phydev Physical Device to bind the VLAN traffic to + # - :bridge Name of the bridge to attach the VMs and VLAN dev to + # - :network_id + def set_up_vlan(options) + + if options[:vlan_id].nil? + options[:vlan_id] = CONF[:start_vlan] + options[:network_id].to_i + end + + options[:vlan_dev] = "#{options[:phydev]}.#{options[:vlan_id]}" + + create_bridge(options[:bridge]) + + return if @bridges[options[:bridge]].include? options[:vlan_dev] + + create_vlan_dev(options) + + OpenNebula.exec_and_log("#{command(:brctl)} addif"\ + " #{options[:bridge]} #{options[:vlan_dev]}") + + @bridges[options[:bridge]] << options[:vlan_dev] + end + + # This function needs to be implemented by any VLAN driver to + # create the VLAN device. The device MUST be set up by this function + # Options is a driver specific hash. It includes + # :vlan_dev the name for the VLAN device + # :phydev Physical Device to bind the VLAN traffic to + # :vlan_id the VLAN ID + # : additional driver specific parameters + def create_vlan_dev(options) + OpenNebula.log_error("create_vlan_dev function not implemented.") + + exit -1 + end + + private + # Creates a bridge if it does not exists, and brings it up. + # This function IS FINAL, exits if action cannot be completed + # @param bridge [String] the bridge name + def create_bridge(bridge) + return if @bridges.keys.include? bridge + + OpenNebula.exec_and_log("#{command(:brctl)} addbr #{bridge}") + + @bridges[bridge] = Array.new + + OpenNebula.exec_and_log("#{command(:ip)} link set #{bridge} up") + end + + # Get hypervisor bridges + # @return [Hash] with the bridge names + def get_bridges + bridges = Hash.new + brctl_exit =`#{VNMNetwork::COMMANDS[:brctl]} show` + + cur_bridge = "" + + brctl_exit.split("\n")[1..-1].each do |l| + l = l.split + + if l.length > 1 + cur_bridge = l[0] + + bridges[cur_bridge] = Array.new + bridges[cur_bridge] << l[3] if l[3] + else + bridges[cur_bridge] << l[0] + end + end + + bridges + end + end +end diff --git a/src/vnm_mad/remotes/lib/vnm_driver.rb b/src/vnm_mad/remotes/lib/vnm_driver.rb index f62df56e06..8ee3ba71c9 100644 --- a/src/vnm_mad/remotes/lib/vnm_driver.rb +++ b/src/vnm_mad/remotes/lib/vnm_driver.rb @@ -35,7 +35,7 @@ module VNMMAD # @param deploy_id [String] # @param hypervisor [String] def initialize(vm_tpl, xpath_filter, deploy_id = nil, hypervisor = nil) - @locking = false + @locking ||= false if !hypervisor @hypervisor = detect_hypervisor @@ -92,30 +92,6 @@ module VNMMAD nil end end - - # Get hypervisor bridges - # @return [Hash] with the bridge names - def get_interfaces - bridges = Hash.new - brctl_exit =`#{VNMNetwork::COMMANDS[:brctl]} show` - - cur_bridge = "" - - brctl_exit.split("\n")[1..-1].each do |l| - l = l.split - - if l.length > 1 - cur_bridge = l[0] - - bridges[cur_bridge] = Array.new - bridges[cur_bridge] << l[3] if l[3] - else - bridges[cur_bridge] << l[0] - end - end - - bridges - end # Returns true if the template contains the deprecated firewall attributes: # - ICMP diff --git a/src/vnm_mad/remotes/lib/vnmmad.rb b/src/vnm_mad/remotes/lib/vnmmad.rb index dad4386931..08c816acdf 100644 --- a/src/vnm_mad/remotes/lib/vnmmad.rb +++ b/src/vnm_mad/remotes/lib/vnmmad.rb @@ -30,7 +30,7 @@ require 'security_groups_iptables' require 'vnm_driver' require 'fw_driver' require 'sg_driver' - +require 'vlan' require 'scripts_common' include OpenNebula diff --git a/src/vnm_mad/remotes/vxlan/clean b/src/vnm_mad/remotes/vxlan/clean new file mode 120000 index 0000000000..940540d063 --- /dev/null +++ b/src/vnm_mad/remotes/vxlan/clean @@ -0,0 +1 @@ +../fw/clean \ No newline at end of file diff --git a/src/vnm_mad/remotes/vxlan/post b/src/vnm_mad/remotes/vxlan/post new file mode 120000 index 0000000000..e0046b5997 --- /dev/null +++ b/src/vnm_mad/remotes/vxlan/post @@ -0,0 +1 @@ +../fw/post \ No newline at end of file diff --git a/src/vnm_mad/remotes/vxlan/pre b/src/vnm_mad/remotes/vxlan/pre new file mode 100755 index 0000000000..a44a58d8a8 --- /dev/null +++ b/src/vnm_mad/remotes/vxlan/pre @@ -0,0 +1,25 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# 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. # +#--------------------------------------------------------------------------- # + +$: << File.dirname(__FILE__) +$: << File.join(File.dirname(__FILE__), "..") + +require 'vxlan_driver' + +hm = VXLANDriver.from_base64(ARGV[0]) +exit hm.activate diff --git a/src/vnm_mad/remotes/vxlan/vxlan_driver.rb b/src/vnm_mad/remotes/vxlan/vxlan_driver.rb new file mode 100644 index 0000000000..c145db4726 --- /dev/null +++ b/src/vnm_mad/remotes/vxlan/vxlan_driver.rb @@ -0,0 +1,54 @@ +# -------------------------------------------------------------------------- # +# 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 'vnmmad' + +################################################################################ +# This driver tag VM traffic with a VLAN_ID using VXLAN protocol. Features: +# - Creates a bridge and bind phisycal device if not present +# - Creates a tagged interface for the VM dev.vlan_id +# +# Once activated the VM will be attached to this bridge +################################################################################ +class VXLANDriver < VNMMAD::VLANDriver + + # DRIVER name and XPATH for relevant NICs + DRIVER = "vxlan" + XPATH_FILTER = "TEMPLATE/NIC[VLAN='YES']" + + ############################################################################ + # Creatges the driver device operations are not locked + ############################################################################ + def initialize(vm, deploy_id = nil, hypervisor = nil) + @locking = false + + super(vm, XPATH_FILTER, deploy_id, hypervisor) + end + + ############################################################################ + # This function creates and activate a VLAN device + ############################################################################ + def create_vlan_dev(options) + mc = VNMMAD::VNMNetwork::IPv4.to_i(CONF[:vxlan_mc]) + options[:vlan_id].to_i + mcs = VNMMAD::VNMNetwork::IPv4.to_s(mc) + + OpenNebula.exec_and_log("#{command(:ip)} link add #{options[:vlan_dev]}"\ + " type vxlan id #{options[:vlan_id]} group #{mcs}"\ + " dev #{options[:phydev]}") + + OpenNebula.exec_and_log("#{command(:ip)} link set #{options[:vlan_dev]} up") + end +end