diff --git a/install.sh b/install.sh index 6e17863d03..6f0306ced4 100755 --- a/install.sh +++ b/install.sh @@ -247,6 +247,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/im/xen3-probes.d \ $VAR_LOCATION/remotes/im/xen4-probes.d \ $VAR_LOCATION/remotes/im/vmware.d \ + $VAR_LOCATION/remotes/im/vcenter.d \ $VAR_LOCATION/remotes/im/ec2.d \ $VAR_LOCATION/remotes/im/sl.d \ $VAR_LOCATION/remotes/im/az.d \ @@ -255,6 +256,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \ $VAR_LOCATION/remotes/vmm/xen3 \ $VAR_LOCATION/remotes/vmm/xen4 \ $VAR_LOCATION/remotes/vmm/vmware \ + $VAR_LOCATION/remotes/vmm/vcenter \ $VAR_LOCATION/remotes/vmm/ec2 \ $VAR_LOCATION/remotes/vmm/sl \ $VAR_LOCATION/remotes/vmm/az \ @@ -407,6 +409,7 @@ INSTALL_FILES=( IM_PROBES_XEN4_FILES:$VAR_LOCATION/remotes/im/xen4.d IM_PROBES_XEN4_PROBES_FILES:$VAR_LOCATION/remotes/im/xen4-probes.d IM_PROBES_VMWARE_FILES:$VAR_LOCATION/remotes/im/vmware.d + IM_PROBES_VCENTER_FILES:$VAR_LOCATION/remotes/im/vcenter.d IM_PROBES_EC2_FILES:$VAR_LOCATION/remotes/im/ec2.d IM_PROBES_SL_FILES:$VAR_LOCATION/remotes/im/sl.d IM_PROBES_AZ_FILES:$VAR_LOCATION/remotes/im/az.d @@ -422,6 +425,7 @@ INSTALL_FILES=( VMM_EXEC_XEN3_SCRIPTS:$VAR_LOCATION/remotes/vmm/xen3 VMM_EXEC_XEN4_SCRIPTS:$VAR_LOCATION/remotes/vmm/xen4 VMM_EXEC_VMWARE_SCRIPTS:$VAR_LOCATION/remotes/vmm/vmware + VMM_EXEC_VCENTER_SCRIPTS:$VAR_LOCATION/remotes/vmm/vcenter VMM_EXEC_EC2_SCRIPTS:$VAR_LOCATION/remotes/vmm/ec2 VMM_EXEC_SL_SCRIPTS:$VAR_LOCATION/remotes/vmm/sl VMM_EXEC_AZ_SCRIPTS:$VAR_LOCATION/remotes/vmm/az @@ -599,6 +603,7 @@ BIN_FILES="src/nebula/oned \ src/cli/onezone \ src/cli/oneflow \ src/cli/oneflow-template \ + src/cli/onevcenter \ src/onedb/onedb \ src/mad/utils/tty_expect \ share/scripts/one" @@ -759,6 +764,28 @@ VMM_EXEC_VMWARE_SCRIPTS="src/vmm_mad/remotes/vmware/cancel \ src/vmm_mad/remotes/vmware/vmware_driver.rb \ src/vmm_mad/remotes/vmware/vi_driver.rb" +#------------------------------------------------------------------------------- +# VMM Driver vCenter scripts, installed under $REMOTES_LOCATION/vmm/vcenter +#------------------------------------------------------------------------------- + +VMM_EXEC_VCENTER_SCRIPTS="src/vmm_mad/remotes/vcenter/cancel \ + src/vmm_mad/remotes/vcenter/attach_disk \ + src/vmm_mad/remotes/vcenter/detach_disk \ + src/vmm_mad/remotes/vcenter/attach_nic \ + src/vmm_mad/remotes/vcenter/detach_nic \ + src/vmm_mad/remotes/vcenter/snapshot_create \ + src/vmm_mad/remotes/vcenter/snapshot_revert \ + src/vmm_mad/remotes/vcenter/snapshot_delete \ + src/vmm_mad/remotes/vcenter/deploy \ + src/vmm_mad/remotes/vcenter/migrate \ + src/vmm_mad/remotes/vcenter/restore \ + src/vmm_mad/remotes/vcenter/reboot \ + src/vmm_mad/remotes/vcenter/reset \ + src/vmm_mad/remotes/vcenter/save \ + src/vmm_mad/remotes/vcenter/poll \ + src/vmm_mad/remotes/vcenter/shutdown \ + src/vmm_mad/remotes/vcenter/vcenter_driver.rb" + #------------------------------------------------------------------------------ # VMM Driver EC2 scripts, to be installed under $REMOTES_LOCATION/vmm/ec2 #------------------------------------------------------------------------------ @@ -870,6 +897,8 @@ IM_PROBES_XEN4_PROBES_FILES="src/im_mad/remotes/xen-probes.d/xen.rb \ IM_PROBES_VMWARE_FILES="src/im_mad/remotes/vmware.d/vmware.rb" +IM_PROBES_VCENTER_FILES="src/im_mad/remotes/vcenter.d/vcenter.rb" + IM_PROBES_EC2_FILES="src/im_mad/remotes/ec2.d/poll" IM_PROBES_SL_FILES="src/im_mad/remotes/sl.d/poll" @@ -1517,7 +1546,8 @@ SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\ src/sunstone/public/js/plugins/support-tab.js \ src/sunstone/public/js/plugins/zones-tab.js" -SUNSTONE_ROUTES_FILES="src/sunstone/routes/oneflow.rb" +SUNSTONE_ROUTES_FILES="src/sunstone/routes/oneflow.rb \ + src/sunstone/routes/vcenter.rb" # begin bower diff --git a/share/etc/oned.conf b/share/etc/oned.conf index 6c8d9cbc04..9c4bef7c4f 100644 --- a/share/etc/oned.conf +++ b/share/etc/oned.conf @@ -310,6 +310,17 @@ IM_MAD = [ # arguments = "-c -t 15 -r 0 vmware" ] #------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- +# vCenter Information Driver Manager Configuration +# -r number of retries when monitoring a host +# -t number of threads, i.e. number of hosts monitored at the same time +#------------------------------------------------------------------------------- +#IM_MAD = [ +# name = "vcenter", +# executable = "one_im_sh", +# arguments = "-c -t 15 -r 0 vcenter" ] +#------------------------------------------------------------------------------- + #------------------------------------------------------------------------------- # EC2 Information Driver Manager Configuration # -r number of retries when monitoring a host @@ -431,6 +442,19 @@ VM_MAD = [ # type = "vmware" ] #------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# vCenter Virtualization Driver Manager Configuration +# -r number of retries when monitoring a host +# -t number of threads, i.e. number of hosts monitored at the same time +#------------------------------------------------------------------------------- +#VM_MAD = [ +# name = "vcenter", +# executable = "one_vmm_sh", +# arguments = "-p -t 15 -r 0 vcenter -s sh", +# type = "xml" ] +#------------------------------------------------------------------------------- + #------------------------------------------------------------------------------- # EC2 Virtualization Driver Manager Configuration # -r number of retries when monitoring a host diff --git a/src/cli/onevcenter b/src/cli/onevcenter new file mode 100644 index 0000000000..c42313e867 --- /dev/null +++ b/src/cli/onevcenter @@ -0,0 +1,217 @@ +#!/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. # +#--------------------------------------------------------------------------- # + +ONE_LOCATION=ENV["ONE_LOCATION"] + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" + REMOTES_LOCATION="/var/lib/one/remotes/" +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" + REMOTES_LOCATION=ONE_LOCATION+"/var/remotes/" +end + +$: << RUBY_LIB_LOCATION +$: << RUBY_LIB_LOCATION+"/cli" +$: << REMOTES_LOCATION+"vmm/vcenter/" + +require 'command_parser' +require 'one_helper/onehost_helper' +require 'one_helper/onecluster_helper' +require 'vcenter_driver' + +cmd=CommandParser::CmdParser.new(ARGV) do + + usage "`onevcenter` [] []" + version OpenNebulaHelper::ONE_VERSION + + helper = OneHostHelper.new + + before_proc do + helper.set_client(options) + end + + ######################################################################## + # Global Options + ######################################################################## + cmd_options=CommandParser::OPTIONS-[CommandParser::VERBOSE] + set :option, cmd_options+OpenNebulaHelper::CLIENT_OPTIONS + + + VCENTER = { + :name => "vcenter", + :large => "--vcenter vCenter" , + :description => "The vCenter hostname", + :format => String + } + + USER = { + :name => "vuser", + :large => "--vuser username" , + :description => "The username to interact with vCenter", + :format => String + } + + PASS = { + :name => "vpass", + :large => "--vpass password", + :description => "The password for the user", + :format => String + } + + ############################################################################ + # Import clusters + ############################################################################ + hosts_desc = <<-EOT.unindent + Import vCenter clusters as OpenNebula hosts + EOT + + command :hosts, hosts_desc, :options=>[ VCENTER, USER, PASS ] do + if options[:vuser].nil? || + options[:vpass].nil? || + options[:vcenter].nil? + STDERR.puts "vCenter connection parameters are mandatory to import"\ + " host:\n"\ + "\t --vcenter vCenter hostname\n"\ + "\t --vuser username to login in vcenter\n"\ + "\t --vpass password for the user" + exit -1 + end + + begin + STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..." + + vc = VCenterDriver::VIClient.new_connection( + :user => options[:vuser], + :password => options[:vpass], + :host => options[:vcenter]) + + STDOUT.print "done!\n\n" + + STDOUT.print "Exploring vCenter resources..." + + rs = vc.hierarchy + + STDOUT.print "done!\n\n" + + rs.each {|dc, cluster| + STDOUT.print "Do you want to process datacenter #{dc} [y/n]? " + + next if STDIN.gets.strip.downcase != 'y' + + if cluster.empty? + STDOUT.puts " No clusters found in #{dc}..." + next + end + + cluster.each{ |c| + STDOUT.print " * Import cluster #{c} [y/n]? " + + next if STDIN.gets.strip.downcase != 'y' + + r, m = VCenterDriver::VCenterHost.to_one(c, vc) + + if r == 0 + STDOUT.puts " OpenNebula host #{c} with id #{m}"\ + " successfully created." + else + STDOUT.puts " Error: #{m}" + end + + STDOUT.puts + } + } + rescue Exception => e + STDOUT.puts "error: #{e.message}" + exit -1 + end + + exit 0 + end + + templates_desc = <<-EOT.unindent + Import vCenter VM Templates into OpenNebula + EOT + + command :templates, templates_desc, :options=>[ VCENTER, USER, PASS ] do + if options[:vuser].nil? || + options[:vpass].nil? || + options[:vcenter].nil? + STDERR.puts "vCenter connection parameters are mandatory to import"\ + " VM templates:\n"\ + "\t --vcenter vCenter hostname\n"\ + "\t --vuser username to login in vcenter\n"\ + "\t --vpass password for the user" + exit -1 + end + + begin + STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..." + + vc = VCenterDriver::VIClient.new_connection( + :user => options[:vuser], + :password => options[:vpass], + :host => options[:vcenter]) + + STDOUT.print "done!\n\n" + + STDOUT.print "Looking for VM Templates..." + + rs = vc.vm_templates + + STDOUT.print "done!\n" + + rs.each {|dc, tmps| + STDOUT.print "\nDo you want to process datacenter #{dc} [y/n]? " + + next if STDIN.gets.strip.downcase != 'y' + + if tmps.empty? + STDOUT.print " No VM Templates found in #{dc}...\n\n" + next + end + + tmps.each{ |t| + STDOUT.print "\n * VM Template found:\n"\ + " - Name : #{t[:name]}\n"\ + " - UUID : #{t[:uuid]}\n"\ + " - Cluster: #{t[:host]}\n"\ + " Import this VM template [y/n]? " + + next if STDIN.gets.strip.downcase != 'y' + + one_t = ::OpenNebula::Template.new( + ::OpenNebula::Template.build_xml, vc.one) + + rc = one_t.allocate(t[:one]) + + if ::OpenNebula.is_error?(rc) + STDOUT.puts " Error creating template: #{rc.message}\n" + else + STDOUT.puts " OpenNebula template #{one_t.id} created!\n" + end + } + } + rescue Exception => e + STDOUT.puts "error: #{e.message}" + exit -1 + end + + exit 0 + end +end diff --git a/src/im_mad/remotes/vcenter.d/vcenter.rb b/src/im_mad/remotes/vcenter.d/vcenter.rb new file mode 100644 index 0000000000..a7b7649632 --- /dev/null +++ b/src/im_mad/remotes/vcenter.d/vcenter.rb @@ -0,0 +1,48 @@ +#!/usr/bin/env ruby + +# ---------------------------------------------------------------------------- # +# Copyright 2010-2014, C12G Labs S.L # +# # +# 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. # +# ---------------------------------------------------------------------------- # + +ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION) + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION) +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION) +end + +$: << "../../vmm/vcenter/" + +require 'vcenter_driver' + +host_id = ARGV[4] + +if !host_id + exit -1 +end + +vi_client = VCenterDriver::VIClient.new host_id + +vcenter_host = VCenterDriver::VCenterHost.new vi_client + +cluster_info = vcenter_host.monitor_cluster +cluster_info << vcenter_host.monitor_host_systems +vm_monitor_info = vcenter_host.monitor_vms + +cluster_info << "\nVM_POLL=YES" +cluster_info << "#{vm_monitor_info}" if !vm_monitor_info.empty? + +puts cluster_info diff --git a/src/mad/ruby/ActionManager.rb b/src/mad/ruby/ActionManager.rb index 2116a3ff65..7a6f6342e9 100644 --- a/src/mad/ruby/ActionManager.rb +++ b/src/mad/ruby/ActionManager.rb @@ -112,7 +112,7 @@ class ActionManager end arity=@actions[aname][:method].arity - + if arity < 0 # Last parameter is an array arity = -arity - 1 @@ -145,7 +145,7 @@ class ActionManager else thread = nil end - + if thread thread.kill @@ -173,17 +173,17 @@ class ActionManager } end end - -private - + + protected + def delete_running_action(action_id) @action_running.delete(action_id) end - + def get_runable_action @action_queue.shift end - + def empty_queue @action_queue.size==0 end @@ -228,13 +228,13 @@ if __FILE__ == $0 @am.register_action(:SLEEP,method("sleep_action")) # @am.register_action(:SLEEP,Proc.new{|s,i| p s ; sleep(s)}) @am.register_action(:NOP,method("nop_action")) - + def @am.get_runable_action action = super puts "getting: #{action.inspect}" action end - + def @am.delete_running_action(action_id) puts "deleting: #{action_id}" super(action_id) @@ -250,7 +250,7 @@ if __FILE__ == $0 def nop_action p " - Just an action" end - + end s = Sample.new @@ -264,7 +264,7 @@ if __FILE__ == $0 } s.am.trigger_action(:SLEEP,301,5,301) - + s.am.cancel_action(301) s.am.trigger_action(:FINALIZE,0) diff --git a/src/mad/ruby/VirtualMachineDriver.rb b/src/mad/ruby/VirtualMachineDriver.rb index ca12065426..21f00cfc2d 100644 --- a/src/mad/ruby/VirtualMachineDriver.rb +++ b/src/mad/ruby/VirtualMachineDriver.rb @@ -77,7 +77,8 @@ class VirtualMachineDriver < OpenNebulaDriver # @option options [Boolean] :threaded (true) enables or disables threads def initialize(directory, options={}) @options={ - :threaded => true + :threaded => true, + :single_host => true }.merge!(options) super(directory, @options) @@ -214,8 +215,17 @@ class VirtualMachineDriver < OpenNebulaDriver end private + # Interface to handle the pending events from the ActionManager Interface def delete_running_action(action_id) + if @options[:single_host] + delete_running_action_single_host(action_id) + else + super(action_id) + end + end + + def delete_running_action_single_host(action_id) action=@action_running[action_id] if action @hosts.delete(action[:host]) @@ -224,6 +234,14 @@ private end def get_first_runable + if @options[:single_host] + get_first_runable_single_host + else + super + end + end + + def get_first_runable_single_host action_index=nil @action_queue.each_with_index do |action, index| if !action.keys.include?(:host) @@ -255,6 +273,14 @@ private end def get_runable_action + if @options[:single_host] + get_runable_action_single_host + else + super + end + end + + def get_runable_action_single_host action_index=get_first_runable if action_index @@ -272,6 +298,14 @@ private end def empty_queue + if @options[:single_host] + empty_queue_single_host + else + super + end + end + + def empty_queue_single_host get_first_runable==nil end end diff --git a/src/oca/ruby/opennebula/virtual_machine.rb b/src/oca/ruby/opennebula/virtual_machine.rb index 5d78a62903..2ad51e0a1c 100644 --- a/src/oca/ruby/opennebula/virtual_machine.rb +++ b/src/oca/ruby/opennebula/virtual_machine.rb @@ -224,7 +224,11 @@ module OpenNebula def deploy(host_id, enforce=false, ds_id=-1) enforce ||= false ds_id ||= -1 - return call(VM_METHODS[:deploy], @pe_id, host_id.to_i, enforce, ds_id.to_i) + return call(VM_METHODS[:deploy], + @pe_id, + host_id.to_i, + enforce, + ds_id.to_i) end # Shutdowns an already deployed VM @@ -587,6 +591,11 @@ module OpenNebula self['GID'].to_i end + # Returns the deploy_id of the VirtualMachine (numeric value) + def deploy_id + self['DEPLOY_ID'] + end + private def action(name) return Error.new('ID not defined') if !@pe_id diff --git a/src/sunstone/OpenNebulaVNC.rb b/src/sunstone/OpenNebulaVNC.rb index a86969a2c3..c6c76768fa 100644 --- a/src/sunstone/OpenNebulaVNC.rb +++ b/src/sunstone/OpenNebulaVNC.rb @@ -172,9 +172,13 @@ class OpenNebulaVNC end # Proxy data - host = vm_resource['/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME'] - vnc_port = vm_resource['TEMPLATE/GRAPHICS/PORT'] - vnc_pw = vm_resource['TEMPLATE/GRAPHICS/PASSWD'] + host = vm_resource['/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME'] + vnc_port = vm_resource['TEMPLATE/GRAPHICS/PORT'] + vnc_pw = vm_resource['TEMPLATE/GRAPHICS/PASSWD'] + + if vm_resource['TEMPLATE/ESX_HOST'] # It is behind a vCenter + host = vm_resource['TEMPLATE/ESX_HOST'] + end # Generate token random_str: host:port random_str = rand(36**20).to_s(36) #random string a-z0-9 length 20 diff --git a/src/sunstone/etc/sunstone-server.conf b/src/sunstone/etc/sunstone-server.conf index 75b9a70bb4..1a69e29e06 100644 --- a/src/sunstone/etc/sunstone-server.conf +++ b/src/sunstone/etc/sunstone-server.conf @@ -189,3 +189,4 @@ :routes: - oneflow + - vcenter diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 698f923f4b..7215f160f5 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -28,8 +28,18 @@ var create_host_tmpl =
\
\
\ - \ - \ + \ + \
\
\ \ @@ -39,17 +49,8 @@ var create_host_tmpl =
\
\
\ - \ - \ + \ + \
\
\
\ @@ -84,6 +85,7 @@ var create_host_tmpl = \ \ \ + \ \ \ \ @@ -105,6 +107,7 @@ var create_host_tmpl = \ \ \ + \ \ \ \ @@ -121,6 +124,39 @@ var create_host_tmpl =
\ \
\ + \
\
\ \ @@ -145,10 +181,6 @@ var host_actions = { call : OpenNebula.Host.create, callback : function(request, response) { // Reset the create wizard - $create_host_dialog.foundation('reveal', 'close'); - $create_host_dialog.empty(); - setupCreateHostDialog(); - addHostElement(request, response); notifyCustom(tr("Host created"), " ID: " + response.HOST.ID, false); }, @@ -431,12 +463,13 @@ function hostElements(){ return getSelectedNodes(dataTable_hosts); } -function generateCPUProgressBar(host) { - var max_cpu = parseInt(host.HOST_SHARE.MAX_CPU); +function generateCPUProgressBar(host, host_share_flag) { + var host_share = host_share_flag ? host : host.HOST_SHARE; + var max_cpu = parseInt(host_share.MAX_CPU); var info_str; - var allocated_cpu = parseInt(host.HOST_SHARE.CPU_USAGE); + var allocated_cpu = parseInt(host_share.CPU_USAGE); if (max_cpu > 0) { var ratio_allocated_cpu = Math.round((allocated_cpu / max_cpu) * 100); @@ -447,7 +480,7 @@ function generateCPUProgressBar(host) { var pb_allocated_cpu = quotaBarHtml(allocated_cpu, max_cpu, info_str); - var real_cpu = parseInt(host.HOST_SHARE.USED_CPU); + var real_cpu = parseInt(host_share.USED_CPU); if (max_cpu > 0) { var ratio_real_cpu = Math.round((real_cpu / max_cpu) * 100); @@ -464,11 +497,12 @@ function generateCPUProgressBar(host) { } } -function generateMEMProgressBar(host){ +function generateMEMProgressBar(host, host_share_flag) { + var host_share = host_share_flag ? host : host.HOST_SHARE; // Generate MEM progress bars - var max_mem = parseInt(host.HOST_SHARE.MAX_MEM); + var max_mem = parseInt(host_share.MAX_MEM); - var allocated_mem = parseInt(host.HOST_SHARE.MEM_USAGE); + var allocated_mem = parseInt(host_share.MEM_USAGE); if (max_mem > 0) { var ratio_allocated_mem = Math.round((allocated_mem / max_mem) * 100); @@ -479,7 +513,7 @@ function generateMEMProgressBar(host){ var pb_allocated_mem = quotaBarHtml(allocated_mem, max_mem, info_str); - var real_mem = parseInt(host.HOST_SHARE.USED_MEM); + var real_mem = parseInt(host_share.USED_MEM); if (max_mem > 0) { var ratio_real_mem = Math.round((real_mem / max_mem) * 100); @@ -859,13 +893,60 @@ function updateHostInfo(request,host){
' } + var esx_info_tab = { + title: tr("ESX"), + icon: "fa-hdd-o", + content : '
\ +
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
' + tr("Hostname") + '' + tr("Status") + '
\ +
\ +
' + } + //Sunstone.updateInfoPanelTab(info_panel_name,tab_name, new tab object); Sunstone.updateInfoPanelTab("host_info_panel","host_info_tab",info_tab); Sunstone.updateInfoPanelTab("host_info_panel","host_monitoring_tab",monitor_tab); Sunstone.updateInfoPanelTab("host_info_panel","host_vms_tab",vms_info_tab); + if (host_info.TEMPLATE.HYPERVISOR == "vcenter") { + Sunstone.updateInfoPanelTab("host_info_panel","host_esx_tab",esx_info_tab); + } + Sunstone.popUpInfoPanel("host_info_panel", "hosts-tab"); + if (host_info.TEMPLATE.HYPERVISOR == "vcenter") { + var dataTable_esx_hosts = $("#datatable_host_esx",main_tabs_context).dataTable({ + "bSortClasses" : false, + "bDeferRender": true + }); + + var host_list_array = []; + $.each(host_info.TEMPLATE.HOST, function(){ + // TODO HOST (esx) keys should match HOST_SHARE keys (FREECPU vs FREE_CPU | TOTAL vs MAX) + //var cpu_bars = generateCPUProgressBar(this, true); + //var mem_bars = generateMEMProgressBar(this, true); + host_list_array.push([ + this.HOSTNAME, + //cpu_bars.real, + //cpu_bars.allocated, + //mem_bars.real, + //mem_bars.allocated, + this.STATE + ]); + }); + dataTable_esx_hosts.fnAddData(host_list_array); + delete host_info.TEMPLATE.HOST; + } + var dataTable_host_vMachines = $("#datatable_host_vms", $("#host_info_panel")).dataTable({ "bSortClasses" : false, "bDeferRender": true, @@ -931,6 +1012,12 @@ function setupCreateHostDialog(){ $create_host_dialog.addClass("reveal-modal medium").attr("data-reveal", ""); $create_host_dialog.foundation() + $("#wizard_host_reset_button", $create_host_dialog).on("click", function(){ + $('#create_host_dialog').html(""); + setupCreateHostDialog(); + popUpCreateHostDialog(); + }) + $(".drivers", $create_host_dialog).hide(); $("#host_type_mad", $create_host_dialog).on("change", function(){ @@ -938,12 +1025,276 @@ function setupCreateHostDialog(){ $("#im_mad", $create_host_dialog).val(this.value).change(); if (this.value == "custom") { + $(".vcenter_credentials", $create_host_dialog).hide(); + $("#vnm_mads", $create_host_dialog).show(); + $("#name", $create_host_dialog).show(); + $("#create_host_submit", $create_host_dialog).show(); $(".drivers", $create_host_dialog).show(); + } else if (this.value == "vcenter") { + $("#vnm_mads", $create_host_dialog).hide(); + $("#name", $create_host_dialog).hide(); + $(".vcenter_credentials", $create_host_dialog).show(); + $("#create_host_submit", $create_host_dialog).hide(); + $(".drivers", $create_host_dialog).hide(); } else { + $(".vcenter_credentials", $create_host_dialog).hide(); + $("#vnm_mads", $create_host_dialog).show(); + $("#name", $create_host_dialog).show(); + $("#create_host_submit", $create_host_dialog).show(); $(".drivers", $create_host_dialog).hide(); } }) + $("#get_vcenter_clusters", $create_host_dialog).on("click", function(){ + // TODO notify if credentials empty + $(".vcenter_clusters", $create_host_dialog).html( + ''+ + ''+ + ''+ + '') + + $.ajax({ + url: '/vcenter', + 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){ + $("#vcenter_user", $create_host_dialog).attr("disabled", "disabled") + $("#vcenter_password", $create_host_dialog).attr("disabled", "disabled") + $("#vcenter_host", $create_host_dialog).attr("disabled", "disabled") + $("#get_vcenter_clusters", $create_host_dialog).hide(); + $(".import_vcenter_clusters_div", $create_host_dialog).show(); + + var vcenter_container = $(".vcenter_clusters", $create_host_dialog); + vcenter_container.html(""); + $('
' + + '
' + + '

' + tr("Please select the vCenter Clusters to be imported to OpenNebula. Each vCenter Cluster will be included as a new OpenNebula Host") + '

' + + '
' + + '
').appendTo(vcenter_container) + + $.each(response, function(datacenter_name, clusters){ + $('
' + + '
' + + '
' + + datacenter_name + ' ' + tr("Clusters") + + '
' + + '
' + + '
').appendTo(vcenter_container) + + if (clusters.length == 0) { + $('
' + + '
' + + '' + + '
' + + '
').appendTo(vcenter_container) + } else { + $.each(clusters, function(id, cluster_name){ + var row = $('
' + + '
' + + '
' + + '' + + '
'+ + '
'+ + '
' + + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
').appendTo(vcenter_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(""); + } + }) + }); + } + }); + }, + error: function(response){ + $(".vcenter_clusters", $create_host_dialog).html('') + onError({}, OpenNebula.Error(response)); + } + }); + + return false; + }) + + + $("#import_vcenter_clusters", $create_host_dialog).on("click", function(){ + $(this).hide(); + + var cluster_id = $('#host_cluster_id .resource_list_select', $create_host_dialog).val(); + if (!cluster_id) cluster_id = "-1"; + + $.each($(".cluster_name:checked", $create_host_dialog), function(){ + var cluster_context = $(this).closest(".vcenter_cluster"); + $(".vcenter_host_result:not(.success)", cluster_context).html(''+ + ''+ + ''+ + ''); + + var host_json = { + "host": { + "name": $(this).data("cluster_name"), + "vm_mad": "vcenter", + "vnm_mad": "dummy", + "im_mad": "vcenter", + "cluster_id": cluster_id + } + }; + + OpenNebula.Host.create({ + timeout: true, + data: host_json, + success: function(request, response) { + OpenNebula.Helper.clear_cache("HOST"); + + $(".vcenter_host_result", cluster_context).addClass("success").html( + ''+ + ''+ + ''+ + ''); + + $(".vcenter_host_response", cluster_context).html('

'+ + tr("Host created successfully")+' ID:'+response.HOST.ID+ + '

'); + + var template_raw = + "VCENTER_USER=\"" + $("#vcenter_user", $create_host_dialog).val() + "\"\n" + + "VCENTER_PASSWORD=\"" + $("#vcenter_password", $create_host_dialog).val() + "\"\n" + + "VCENTER_HOST=\"" + $("#vcenter_host", $create_host_dialog).val() + "\"\n"; + + 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?"))+ + '

'); + } + }); + }) + }, + error: function (request, error_json){ + $(".vcenter_host_result", context).html(''+ + ''+ + ''+ + ''); + + $(".vcenter_host_response", context).html('

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

'); + } + }); + }) + + return false + }); + // Show custom driver input only when custom is selected in selects $('input[name="custom_vmm_mad"],'+ 'input[name="custom_im_mad"],'+ @@ -1007,13 +1358,17 @@ function setupCreateHostDialog(){ //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); - $('div#create_host_dialog').foundation('reveal', 'open'); - $("input#name",$('div#create_host_dialog')).focus(); + $("#create_host_dialog").foundation('reveal', 'open'); + $("input#name",$("#create_host_dialog")).focus(); return false; } diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index f62001a12a..97a8d5abdc 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -784,16 +784,17 @@ function generate_capacity_tab_content() { ''+ ''+ ''+ + ''+ '
'+ '
'+ '
'+ - '
'+ + '
'+ ''+ '