From 5d44f6e758d447e4f10215c218773766a42adf87 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 5 Jan 2015 02:31:03 +0100 Subject: [PATCH 01/17] feature #3208: Implement VXLAN support. Moved common bridge functions from 802.1Q to VLANDriver class. Rename vlan_driver to vlan_tag_driver for 802.1Q. --- install.sh | 11 +- src/vnm_mad/remotes/802.1Q/pre | 4 +- .../{vlan_driver.rb => vlan_tag_driver.rb} | 85 +++----------- src/vnm_mad/remotes/OpenNebulaNetwork.conf | 7 ++ src/vnm_mad/remotes/lib/vlan.rb | 110 ++++++++++++++++++ src/vnm_mad/remotes/lib/vnm_driver.rb | 26 +---- src/vnm_mad/remotes/lib/vnmmad.rb | 2 +- src/vnm_mad/remotes/vxlan/clean | 1 + src/vnm_mad/remotes/vxlan/post | 1 + src/vnm_mad/remotes/vxlan/pre | 25 ++++ src/vnm_mad/remotes/vxlan/vxlan_driver.rb | 81 +++++++++++++ 11 files changed, 256 insertions(+), 97 deletions(-) rename src/vnm_mad/remotes/802.1Q/{vlan_driver.rb => vlan_tag_driver.rb} (56%) create mode 100644 src/vnm_mad/remotes/lib/vlan.rb create mode 120000 src/vnm_mad/remotes/vxlan/clean create mode 120000 src/vnm_mad/remotes/vxlan/post create mode 100755 src/vnm_mad/remotes/vxlan/pre create mode 100644 src/vnm_mad/remotes/vxlan/vxlan_driver.rb diff --git a/install.sh b/install.sh index 6c9907c2fd..0f9a450e15 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 @@ -940,6 +942,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" @@ -947,7 +950,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/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_tag_driver.rb similarity index 56% rename from src/vnm_mad/remotes/802.1Q/vlan_driver.rb rename to src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb index f3dcf5dabc..a06bee77c0 100644 --- a/src/vnm_mad/remotes/802.1Q/vlan_driver.rb +++ b/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb @@ -23,7 +23,7 @@ require 'vnmmad' # # Once activated the VM will be attached to this bridge ################################################################################ -class VLANDriver < VNMMAD::VNMDriver +class VLANTagDriver < VNMMAD::VLANDriver # DRIVER name and XPATH for relevant NICs DRIVER = "802.1Q" @@ -33,12 +33,9 @@ class VLANDriver < VNMMAD::VNMDriver # 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 + super(vm, XPATH_FILTER, deploy_id, hypervisor) end ############################################################################ @@ -47,33 +44,21 @@ class VLANDriver < VNMMAD::VNMDriver def activate lock - vm_id = @vm['ID'] + vm_id = @vm['ID'] + options = Hash.new 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 + options.clear - if !bridge_exists? bridge - create_bridge bridge - ifup bridge - end + options[:bridge] = nic[:bridge] + options[:phydev] = nic[:phydev] + options[:vlan_id] = nic[:vlan_id] + options[:network_id] = nic[:network_id] - if !device_exists?(dev, vlan) - create_dev_vlan(dev, vlan) - ifup(dev, vlan) - end + return if options[:phydev].nil? - if !attached_bridge_dev?(bridge, dev, vlan) - attach_brigde_dev(bridge, dev, vlan) - end - end + set_up_vlan(options) end unlock @@ -82,49 +67,13 @@ class VLANDriver < VNMMAD::VNMDriver end ############################################################################ - # Private interface, methods to manage bridges and VLAN tags through the - # brctl and ip commands + # This function creates and activate a VLAN device ############################################################################ - private + 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]}") - 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") + 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..0336f72b9c --- /dev/null +++ b/src/vnm_mad/remotes/lib/vlan.rb @@ -0,0 +1,110 @@ +# -------------------------------------------------------------------------- # +# 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 + + # 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 + + # 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 + + 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..7dda6b0bf3 --- /dev/null +++ b/src/vnm_mad/remotes/vxlan/vxlan_driver.rb @@ -0,0 +1,81 @@ +# -------------------------------------------------------------------------- # +# 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 + + ############################################################################ + # 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 + + ############################################################################ + # 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 From 5759fb384316109354e8bfe9dfbe4e3635e30ac4 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 5 Jan 2015 16:37:43 +0100 Subject: [PATCH 02/17] feature #3208: Move common activate function to VLANDriver base class --- src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb | 28 ----------- src/vnm_mad/remotes/lib/vlan.rb | 47 ++++++++++++++----- src/vnm_mad/remotes/vxlan/vxlan_driver.rb | 27 ----------- 3 files changed, 36 insertions(+), 66 deletions(-) diff --git a/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb b/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb index a06bee77c0..bc2f6c0ce1 100644 --- a/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb +++ b/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb @@ -38,34 +38,6 @@ class VLANTagDriver < VNMMAD::VLANDriver super(vm, XPATH_FILTER, deploy_id, hypervisor) end - ############################################################################ - # Activate the driver and creates bridges and tags devices as needed. - ############################################################################ - def activate - lock - - vm_id = @vm['ID'] - 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 - ############################################################################ # This function creates and activate a VLAN device ############################################################################ diff --git a/src/vnm_mad/remotes/lib/vlan.rb b/src/vnm_mad/remotes/lib/vlan.rb index 0336f72b9c..0a2f20e951 100644 --- a/src/vnm_mad/remotes/lib/vlan.rb +++ b/src/vnm_mad/remotes/lib/vlan.rb @@ -31,17 +31,29 @@ module VNMMAD unlock 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.") + # Activate the driver and creates bridges and tags devices as needed. + def activate + lock - exit -1 + 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. @@ -68,7 +80,20 @@ module VNMMAD @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 diff --git a/src/vnm_mad/remotes/vxlan/vxlan_driver.rb b/src/vnm_mad/remotes/vxlan/vxlan_driver.rb index 7dda6b0bf3..c145db4726 100644 --- a/src/vnm_mad/remotes/vxlan/vxlan_driver.rb +++ b/src/vnm_mad/remotes/vxlan/vxlan_driver.rb @@ -38,33 +38,6 @@ class VXLANDriver < VNMMAD::VLANDriver super(vm, XPATH_FILTER, deploy_id, hypervisor) 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 - ############################################################################ # This function creates and activate a VLAN device ############################################################################ From 7ca6790f6bbcdd5983b5fc226fdcdbe422333e55 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Wed, 14 Jan 2015 18:10:16 +0100 Subject: [PATCH 03/17] feature #3330: Filter existing templates and nets (cherry picked from commit 3af8bad7cdb665d2de2b823146d2147e582d63f4) --- src/cli/onevcenter | 4 +- src/vmm_mad/remotes/vcenter/vcenter_driver.rb | 108 +++++++++++------- 2 files changed, 67 insertions(+), 45 deletions(-) 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/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 From b90b40b3615b9029c7843449ecc653a07ef96377 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Wed, 14 Jan 2015 18:11:22 +0100 Subject: [PATCH 04/17] feature #3330: Add option to reacquire vcenter templates and networks from the host create dialog (cherry picked from commit 3ba36da6247880b32d19b43601df779c4b4b2b97) --- src/sunstone/public/js/plugins/hosts-tab.js | 792 +++++++++++--------- src/sunstone/routes/vcenter.rb | 22 +- 2 files changed, 455 insertions(+), 359 deletions(-) diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index aaf4fb6392..2e203443d3 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 +1419,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 +1435,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 +1520,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 +1534,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 }); 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 From b1ea19e192fd670ffa3402b3eb7b2706809fe223 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Fri, 16 Jan 2015 17:11:18 +0100 Subject: [PATCH 05/17] feature #3126: Define search type for search inputs --- src/sunstone/public/js/plugins/acls-tab.js | 2 +- src/sunstone/public/js/plugins/clusters-tab.js | 2 +- src/sunstone/public/js/plugins/datastores-tab.js | 2 +- src/sunstone/public/js/plugins/files-tab.js | 2 +- src/sunstone/public/js/plugins/groups-tab.js | 2 +- src/sunstone/public/js/plugins/hosts-tab.js | 2 +- src/sunstone/public/js/plugins/images-tab.js | 2 +- src/sunstone/public/js/plugins/marketplace-tab.js | 2 +- src/sunstone/public/js/plugins/oneflow-services.js | 2 +- src/sunstone/public/js/plugins/oneflow-templates.js | 2 +- src/sunstone/public/js/plugins/secgroups-tab.js | 2 +- src/sunstone/public/js/plugins/support-tab.js | 2 +- src/sunstone/public/js/plugins/templates-tab.js | 12 ++++++------ src/sunstone/public/js/plugins/users-tab.js | 2 +- src/sunstone/public/js/plugins/vms-tab.js | 2 +- src/sunstone/public/js/plugins/vnets-tab.js | 2 +- src/sunstone/public/js/plugins/zones-tab.js | 2 +- src/sunstone/public/js/sunstone.js | 2 +- 18 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/sunstone/public/js/plugins/acls-tab.js b/src/sunstone/public/js/plugins/acls-tab.js index 73873f63f8..34bdad0dbb 100644 --- a/src/sunstone/public/js/plugins/acls-tab.js +++ b/src/sunstone/public/js/plugins/acls-tab.js @@ -260,7 +260,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 295b2f6e45..25d86ea58b 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 96c963921b..0660070a7c 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 0af6308317..628e3c9a0f 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 a1ae7b6bc3..9f11b71da9 100644 --- a/src/sunstone/public/js/plugins/groups-tab.js +++ b/src/sunstone/public/js/plugins/groups-tab.js @@ -438,7 +438,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: '\ diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 2e203443d3..5a5db41350 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -435,7 +435,7 @@ var hosts_tab = { buttons: host_buttons, tabClass: "subTab", parentTab: "infra-tab", - search_input: '', + search_input: '', list_header: ' '+tr("Hosts"), info_header: ' '+tr("Host"), subheader: ' '+tr("TOTAL")+' \ diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index 1c9fa1effe..124298c98e 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/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..7a33920896 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: '\ diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index f2c04c01d3..75a85c2070 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")+' \ diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 92f3ce0565..61e81cdeff 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -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 df77802393..ba444b3773 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 b6b12b3e07..b50f00686a 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -6810,7 +6810,7 @@ function generateResourceTableSelect(context_id, columns, options){ \
\
\ - \ + \
\ \
\ From ae78f395981e1cdee6cd1d8718e0ae098cb4defe Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Fri, 16 Jan 2015 17:26:03 +0100 Subject: [PATCH 06/17] bug #3506: Ignore empty interfaces --- src/sunstone/public/js/plugins/provision-tab.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/sunstone/public/js/plugins/provision-tab.js b/src/sunstone/public/js/plugins/provision-tab.js index 4bbdd07e40..c86dd6cb9f 100644 --- a/src/sunstone/public/js/plugins/provision-tab.js +++ b/src/sunstone/public/js/plugins/provision-tab.js @@ -6328,16 +6328,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); From c1f4046e56338c556463713c9dab90fa30630f9e Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Fri, 16 Jan 2015 17:52:02 +0100 Subject: [PATCH 07/17] bug #3273: Do not close host dialog after reset --- src/sunstone/public/js/plugins/hosts-tab.js | 33 +++++++++++---------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 5a5db41350..19a8040ee0 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -1331,9 +1331,7 @@ function setupCreateHostDialog(){ $create_host_dialog.foundation() $("#wizard_host_reset_button", $create_host_dialog).on("click", function(){ - $('#create_host_dialog').html(""); - setupCreateHostDialog(); - popUpCreateHostDialog(); + resetCreateHostDialog(); }) $(".drivers", $create_host_dialog).hide(); @@ -1736,20 +1734,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 From 9f7277ee0821ba00460ef5e27757aa8b993b0ac3 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Mon, 19 Jan 2015 11:56:02 +0100 Subject: [PATCH 08/17] feature #3336: Add proxy support to the zendesk client --- src/sunstone/routes/support.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 From fa7831965bc03bf4ca7a9fe1895e651d7658d915 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Mon, 19 Jan 2015 16:11:18 +0100 Subject: [PATCH 09/17] bug #3272: Disable enter action in host creation form --- src/sunstone/public/js/plugins/hosts-tab.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 19a8040ee0..a03fc715d1 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -1699,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(); From eba9ef50f0a0a5f47c78a0876be181f822fd7648 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Mon, 19 Jan 2015 16:24:18 +0100 Subject: [PATCH 10/17] bug #3503: Clear custom attributes section --- src/sunstone/public/js/plugins/provision-tab.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sunstone/public/js/plugins/provision-tab.js b/src/sunstone/public/js/plugins/provision-tab.js index c86dd6cb9f..5501e4ecee 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(""); } } From 42b531d227b28aa348ff63dfa064070ed8434484 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Mon, 19 Jan 2015 17:07:20 +0100 Subject: [PATCH 11/17] bug #3497: Fix showback tabs initialization --- src/sunstone/public/js/plugins/groups-tab.js | 8 +++++--- src/sunstone/public/js/plugins/users-tab.js | 9 ++++++--- src/sunstone/public/js/sunstone.js | 4 ---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/sunstone/public/js/plugins/groups-tab.js b/src/sunstone/public/js/plugins/groups-tab.js index 9f11b71da9..617374c1f8 100644 --- a/src/sunstone/public/js/plugins/groups-tab.js +++ b/src/sunstone/public/js/plugins/groups-tab.js @@ -747,14 +747,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/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index 7a33920896..c9ddb7e0f8 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -635,13 +635,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"), diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index b50f00686a..05fdf43a7b 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -4797,10 +4797,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( '
\
\ From 00d1b0f5419a53aa1caedb3aacdef988a0a44401 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Mon, 19 Jan 2015 17:13:10 +0100 Subject: [PATCH 12/17] bug #3420: Truncate vm cost --- src/sunstone/public/js/plugins/provision-tab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sunstone/public/js/plugins/provision-tab.js b/src/sunstone/public/js/plugins/provision-tab.js index 5501e4ecee..35aa0f493a 100644 --- a/src/sunstone/public/js/plugins/provision-tab.js +++ b/src/sunstone/public/js/plugins/provision-tab.js @@ -2319,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(); } @@ -2428,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"); From 9ddae9673b2e3de4d22805de96e36a4c73485d95 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Mon, 19 Jan 2015 17:17:37 +0100 Subject: [PATCH 13/17] bug #3504: Datatable not defined when trying to initalize the select filter --- src/sunstone/public/js/plugins/provision-tab.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sunstone/public/js/plugins/provision-tab.js b/src/sunstone/public/js/plugins/provision-tab.js index 35aa0f493a..9a1289b824 100644 --- a/src/sunstone/public/js/plugins/provision-tab.js +++ b/src/sunstone/public/js/plugins/provision-tab.js @@ -4308,7 +4308,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); } }) @@ -4462,7 +4462,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); } }) @@ -5178,7 +5178,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); } }) From 8216b97ff33043b60884899a81bcd4fd7edce04f Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Tue, 20 Jan 2015 11:57:56 +0100 Subject: [PATCH 14/17] feature #3345: Set Date.now as max for accounting --- src/sunstone/public/js/sunstone.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index 05fdf43a7b..ea54851e70 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -5399,10 +5399,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 @@ -5419,6 +5425,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 //-------------------------------------------------------------------------- From ce5544e1e5c569aa6681ebe4804af258ab1ea557 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Tue, 20 Jan 2015 12:03:49 +0100 Subject: [PATCH 15/17] bug #3101: Fix configuration title --- src/sunstone/public/js/plugins/vnets-tab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 61e81cdeff..8c950fce75 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")+'
\ From f127a7f80cd4286f979ef581b5f363db007a7093 Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Wed, 21 Jan 2015 11:22:57 +0100 Subject: [PATCH 16/17] feature #3416: Add a hidden column including the vm info --- src/sunstone/etc/sunstone-views/admin.yaml | 1 + src/sunstone/etc/sunstone-views/user.yaml | 1 + src/sunstone/etc/sunstone-views/vcenter.yaml | 1 + src/sunstone/public/js/plugins/users-tab.js | 14 ++------------ src/sunstone/public/js/plugins/vms-tab.js | 8 ++++++-- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/sunstone/etc/sunstone-views/admin.yaml b/src/sunstone/etc/sunstone-views/admin.yaml index b9999f795f..ce2f52d623 100644 --- a/src/sunstone/etc/sunstone-views/admin.yaml +++ b/src/sunstone/etc/sunstone-views/admin.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/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/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index c9ddb7e0f8..8b95a8085b 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -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 [ '', @@ -886,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 75a85c2070..64c9d44941 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -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(){ From 0d1a0992e5fde3e404b1e40fe73d86cd7090afdc Mon Sep 17 00:00:00 2001 From: Daniel Molina Date: Wed, 21 Jan 2015 11:45:05 +0100 Subject: [PATCH 17/17] feature #3011: Disable novnc button in cloud view if it's not enabled in the VM --- src/sunstone/public/js/plugins/provision-tab.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/sunstone/public/js/plugins/provision-tab.js b/src/sunstone/public/js/plugins/provision-tab.js index 9a1289b824..6670441c57 100644 --- a/src/sunstone/public/js/plugins/provision-tab.js +++ b/src/sunstone/public/js/plugins/provision-tab.js @@ -3708,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);