From 4f1bb077c5591f45e5c862dfce768c5d1ee49ad0 Mon Sep 17 00:00:00 2001
From: Sergio Semedi Barranco <ssemedi@opennebula.org>
Date: Mon, 5 Mar 2018 11:26:11 +0100
Subject: [PATCH] B #1793: Fix vCenter network/disk moniroring (#1819)

---
 .../remotes/lib/vcenter_driver/host.rb        | 45 +++++++------------
 .../lib/vcenter_driver/virtual_machine.rb     | 31 ++++++++-----
 2 files changed, 36 insertions(+), 40 deletions(-)

diff --git a/src/vmm_mad/remotes/lib/vcenter_driver/host.rb b/src/vmm_mad/remotes/lib/vcenter_driver/host.rb
index b7e81318b2..e64fbbdc1a 100644
--- a/src/vmm_mad/remotes/lib/vcenter_driver/host.rb
+++ b/src/vmm_mad/remotes/lib/vcenter_driver/host.rb
@@ -434,9 +434,14 @@ class ClusterComputeResource
 
         vm_pool = VCenterDriver::VIHelper.one_pool(OpenNebula::VirtualMachinePool)
 
+        # opts common to all vms
+        opts = {
+            pool: vm_pool,
+            vc_uuid: vc_uuid,
+        }
+
         vms.each do |vm_ref,info|
             begin
-                vm = VCenterDriver::VirtualMachine.new_without_id(@vi_client, vm_ref)
                 esx_host = esx_hosts[info["runtime.host"]._ref]
                 info[:esx_host_name] = esx_host[:name]
                 info[:esx_host_cpu] = esx_host[:cpu]
@@ -446,10 +451,6 @@ class ClusterComputeResource
                 info[:host_id] = host_id
                 info[:rp_list] = @rp_list
 
-                vm.vm_info = info
-
-                number = -1
-
                 # Check the running flag
                 running_flag = info["config.extraConfig"].select do |val|
                     val[:key] == "opennebula.vm.running"
@@ -461,41 +462,29 @@ class ClusterComputeResource
 
                 next if running_flag == "no"
 
-                # Extract vmid if possible
-                matches = info["name"].match(/^one-(\d*)(-(.*))?$/)
-                number  = matches[1] if matches
+                # retrieve vcenter driver machine
+                vm = VCenterDriver::VirtualMachine.new_from_ref(@vi_client, vm_ref, info["name"], opts)
+                id = vm.vm_id
 
-                # Extract vmid from ref and vcenter instance uuid if possible
-                one_vm = nil
-                if number == -1
-                    one_vm = VCenterDriver::VIHelper.find_by_ref(OpenNebula::VirtualMachinePool,
-                                                                "DEPLOY_ID",
-                                                                vm_ref,
-                                                                vc_uuid,
-                                                                vm_pool)
-                    if one_vm
-                        number = one_vm["ID"]
-
-                        next if @monitored_vms.include? number
-                        @monitored_vms << number
-
-                        vm.one_item = one_vm
-                        vm.vm_id = number
-                    end
+                #skip if it's already monitored
+                if vm.one_exist?
+                    next if @monitored_vms.include? id
+                    @monitored_vms << id
                 end
 
+                vm.vm_info = info
                 vm.monitor(stats)
 
                 vm_name = "#{info["name"]} - #{cluster_name}"
-
                 str_info << %Q{
                 VM = [
-                    ID="#{number}",
+                    ID="#{id}",
                     VM_NAME="#{vm_name}",
                     DEPLOY_ID="#{vm_ref}",
                 }
 
-                if number == -1
+                # if the machine does not exist in opennebula it means that is a wild:
+                unless vm.one_exist?
                     vm_template_64 = Base64.encode64(vm.vm_to_one(vm_name)).gsub("\n","")
                     str_info << "VCENTER_TEMPLATE=\"YES\","
                     str_info << "IMPORT_TEMPLATE=\"#{vm_template_64}\","
diff --git a/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb b/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb
index a370fc8b30..a9112e3051 100644
--- a/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb
+++ b/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb
@@ -981,6 +981,11 @@ class VirtualMachine < Template
         !get_vm_id
     end
 
+    # @return Boolean wheter the vm exists in opennebubla
+    def one_exist?
+        !@vm_id.nil? && @vm_id != -1
+    end
+
     # @return String the vm_id stored in vCenter
     def get_vm_id(vm_pool = nil)
         if defined?(@vm_id) && @vm_id
@@ -3088,24 +3093,25 @@ class VirtualMachine < Template
     # STATIC MEMBERS AND CONSTRUCTORS
     ###############################################################################################
 
-    def self.get_id(opts = {})
-        id = -1
-
+    def self.get_vm(opts = {})
+        # try to retrieve machine from name
         if (opts[:name])
                 matches = opts[:name].match(/^one-(\d*)(-(.*))?$/)
-                id = matches[1] if matches
+                if matches
+                    id = matches[1]
+                    one_vm = VCenterDriver::VIHelper.one_item(OpenNebula::VirtualMachine, id)
+                end
         end
 
-        if id == -1
+        if one_vm.nil?
             one_vm = VCenterDriver::VIHelper.find_by_ref(OpenNebula::VirtualMachinePool,
                                                          "DEPLOY_ID",
                                                          opts[:ref],
                                                          opts[:vc_uuid],
                                                          opts[:pool])
-            id = one_vm["ID"] if one_vm
         end
 
-        return id
+        return one_vm
     end
 
     # Try to build the vcenterdriver virtualmachine without
@@ -3119,16 +3125,17 @@ class VirtualMachine < Template
     #        :name:    the vcenter vm name for extract the opennebula id
     #
     # @return [vcenterdriver::vm] the virtual machine
-    def self.new_from_ref(vi_client, ref, opts = {})
+    def self.new_from_ref(vi_client, ref, name, opts = {})
         unless opts[:vc_uuid]
             opts[:vc_uuid] = vi_client.vim.serviceContent.about.instanceUuid
         end
 
-        opts[:ref] = ref
+        opts[:name] = name
+        opts[:ref]  = ref
 
-        vm_id = VCenterDriver::VirtualMachine.get_id(opts)
+        one_vm = VCenterDriver::VirtualMachine.get_vm(opts)
 
-        self.new(vi_client, ref, vm_id)
+        self.new_one(vi_client, ref, one_vm)
     end
 
     # build a vcenterdriver virtual machine from a template
@@ -3156,7 +3163,7 @@ class VirtualMachine < Template
     #
     # @return [vcenterdriver::vm] the virtual machine
     def self.new_one(vi_client, ref, one_item)
-        id = one_item["ID"] || one_item["VM/ID"] || -1
+        id = one_item["ID"] || one_item["VM/ID"] rescue -1
 
         self.new(vi_client, ref, id).tap do |vm|
             vm.one_item = one_item