fog/fog-vsphere

View on GitHub
lib/fog/vsphere/requests/compute/get_folder.rb

Summary

Maintainability
A
1 hr
Test Coverage
module Fog
  module Vsphere
    class Compute
      class Real
        def get_folder(path, datacenter_name, type = nil)
          type ||= 'vm'
          # Cycle through all types of folders.
          folder = get_raw_folder(path, datacenter_name, type)
          raise(Fog::Vsphere::Compute::NotFound) unless folder
          folder_attributes(folder, datacenter_name)
        end

        protected

        def get_raw_folder(path, datacenter_name_or_obj, type)
          # The required path syntax - 'topfolder/subfolder

          # Clean up path to be relative since we're providing datacenter name
          dc = if datacenter_name_or_obj.is_a?(String)
                 find_raw_datacenter(datacenter_name_or_obj)
               else
                 datacenter_name_or_obj
               end

          valid_types = %w[vm network datastore host]
          raise ArgumentError, "#{type} is unknown" if type.nil? || type.empty?
          raise "Invalid type (#{type}). Must be one of #{valid_types.join(', ')} " unless valid_types.include?(type.to_s)
          meth = "#{type}Folder"
          dc_root_folder = dc.send(meth)

          # Filter the root path for this datacenter not to be used."
          dc_root_folder_path = dc_root_folder.path.map { |_, name| name }.join('/')
          paths = path.sub(/^\/?#{Regexp.quote(dc_root_folder_path)}\/?/, '').split('/')

          return dc_root_folder if paths.empty?
          # Walk the tree resetting the folder pointer as we go
          paths.reduce(dc_root_folder) do |last_returned_folder, sub_folder|
            # JJM VIM::Folder#find appears to be quite efficient as it uses the
            # searchIndex It certainly appears to be faster than
            # VIM::Folder#inventory since that returns _all_ managed objects of
            # a certain type _and_ their properties.
            sub = last_returned_folder.find(sub_folder, RbVmomi::VIM::Folder)
            raise Fog::Vsphere::Compute::NotFound, "Could not descend into #{sub_folder}.  Please check your path. #{path}" unless sub
            sub
          end
        end

        def get_raw_vmfolder(path, datacenter_name)
          get_raw_folder(path, datacenter_name, 'vm')
        end

        def folder_attributes(folder, datacenter_name)
          {
            id: managed_obj_id(folder),
            name: folder.name,
            parent: folder.parent.name,
            datacenter: datacenter_name,
            type: folder_type(folder.childType),
            path: folder_path(folder)
          }
        end

        def folder_path(folder)
          '/' + folder.path.map(&:last).join('/')
        end

        def folder_type(types)
          return :vm        if types.include?('VirtualMachine')
          return :network   if types.include?('Network')
          return :datastore if types.include?('Datastore')
          return :host      if types.include?('ComputeResource')
        end
      end

      class Mock
        def get_folder(path, datacenter_name, _type = nil)
          data[:folders].values.find { |f| (f['datacenter'] == datacenter_name) && f['path'].end_with?(path) } ||
            raise(Fog::Vsphere::Compute::NotFound)
        end
      end
    end
  end
end