fog / fog-vsphere

Fog for vSphere
MIT License
36 stars 63 forks source link

compute.rb: Datacenter cannot be determined if user does not have permission to hosts #174

Closed manchiu closed 5 years ago

manchiu commented 6 years ago

I do not have the permission to access the Hosts. At the same time, I have the permission to access the Datacenter of the VM. However, currently the implementation does not allow me to retrieve the Datacenter as it is using the Host to derive Datacenter.

if attrs['hypervisor'].is_a?(RbVmomi::VIM::HostSystem)
  host = attrs['hypervisor']
  attrs['datacenter'] = proc {
    begin
               parent_attribute(host.path, :datacenter)[1]
             rescue
               nil
             end
  }
  attrs['cluster'] = proc {
    begin
               parent_attribute(host.path, :cluster)[1]
             rescue
               nil
             end
  }
  attrs['hypervisor'] = proc {
    begin
               host.name
             rescue
               nil
             end
  }
  attrs['resource_pool'] = proc {
    begin
              (vm_mob_ref.resourcePool || host.resourcePool).name
            rescue
              nil
            end
  }
end

My suggestion is to add a fall back mechanism which is to use the VM itself (vm_mob_ref.path) to derive the Datacenter if user does not have permission to the hosts.

if attrs['hypervisor'].is_a?(RbVmomi::VIM::HostSystem)
  host = attrs['hypervisor']

  # @note
  #   - User might not have permission to access host
  #   - i.e. host.name might raise NoPermission error
  has_permission_to_access_host = true
  begin
    host.name
  rescue RbVmomi::Fault => e
    raise e unless e.message && e.message['NoPermission:']
    has_permission_to_access_host = false
  end

  attrs['datacenter'] = proc {
    begin
      if has_permission_to_access_host
        parent_attribute(host.path, :datacenter)[1]
      else
        parent_attribute(vm_mob_ref.path, :datacenter)[1]
      end
    rescue
      nil
    end
  }
  attrs['cluster'] = proc {
    begin
      parent_attribute(host.path, :cluster)[1]
    rescue
      nil
    end
  }
  attrs['hypervisor'] = proc {
    begin
      host.name
    rescue
      nil
    end
  }
  attrs['resource_pool'] = proc {
    begin
      (vm_mob_ref.resourcePool || host.resourcePool).name
    rescue
      nil
    end
  }
end

Please feel free to comment. Thanks!

chris1984 commented 6 years ago

@manchiu did you want to submit a pr for this? Happy to test, if not we can get to it when we can.

manchiu commented 6 years ago

@chris1984 Sure. I can submit a pr for this