app/models/ems_folder.rb
class EmsFolder < ApplicationRecord
include NewWithTypeStiMixin
belongs_to :ext_management_system, :foreign_key => "ems_id"
acts_as_miq_taggable
include ProviderObjectMixin
include RelationshipMixin
self.default_relationship_type = "ems_metadata"
include RelationshipsAggregationMixin
include AggregationMixin::Methods
include MiqPolicyMixin
virtual_has_many :vms_and_templates, :uses => :all_relationships
virtual_has_many :vms, :uses => :all_relationships
virtual_has_many :miq_templates, :uses => :all_relationships
virtual_has_many :hosts, :uses => :all_relationships
virtual_has_many :storages, :uses => :all_relationships
virtual_attribute :folder_path, :string, :uses => :all_relationships
delegate :queue_name_for_ems_operations, :to => :ext_management_system, :allow_nil => true
delegate :my_zone, :to => :ext_management_system
#
# Relationship methods
#
# Folder relationship methods
def folders
children(:of_type => 'EmsFolder')
end
alias_method :add_folder, :set_child
alias_method :remove_folder, :remove_child
def remove_all_folders
remove_all_children(:of_type => 'EmsFolder')
end
def folders_only
folders.select { |f| !f.kind_of?(Datacenter) }
end
def datacenters_only
folders.select { |f| f.kind_of?(Datacenter) }
end
# Cluster relationship methods
def clusters
children(:of_type => 'EmsCluster')
end
alias_method :add_cluster, :set_child
alias_method :remove_cluster, :remove_child
def remove_all_clusters
remove_all_children(:of_type => 'EmsCluster')
end
# Host relationship methods
# all_hosts and all_host_ids included from AggregationMixin
def hosts
children(:of_type => 'Host')
end
alias_method :add_host, :set_child
alias_method :remove_host, :remove_child
def remove_all_hosts
remove_all_children(:of_type => 'Host')
end
# Vm relationship methods
# all_vms and all_vm_ids included from AggregationMixin
def vms_and_templates
children(:of_type => 'VmOrTemplate')
end
def miq_templates
vms_and_templates.select { |v| v.kind_of?(MiqTemplate) }
end
def vms
vms_and_templates.select { |v| v.kind_of?(Vm) }
end
alias_method :add_vm, :set_child
alias_method :remove_vm, :remove_child
def remove_all_vms
remove_all_children(:of_type => 'Vm')
end
def storages
children(:of_type => 'Storage')
end
alias add_storage set_child
alias remove_storage remove_child
def remove_all_storages
remove_all_children(:of_type => 'Storage')
end
# Parent relationship methods
def parent_datacenter
detect_ancestor(:of_type => "EmsFolder") { |a| a.kind_of?(Datacenter) }
end
# Indicates if the folder is able to have child VMs
def vm_folder?
path.any? { |folder| folder.name == "vm" && folder.hidden? }
end
def register_host(_host)
raise NotImplementedError, _("register_host must be implemented by a subclass")
end
# Folder pathing methods
# TODO: Store the full path directly in the folder objects for performance reasons
# Returns an array of all parent folders with options for excluding "hidden"
# folders. Default options are:
# :exclude_root_folder => false
# :exclude_non_display_folders => false
def folder_path_objs(*args)
options = args.extract_options!
folders = path(:of_type => "EmsFolder")
folders = folders[1..-1] if options[:exclude_root_folder]
folders = folders.reject(&:hidden?) if options[:exclude_non_display_folders]
folders
end
def folder_path(*args)
folder_path_objs(*args).collect(&:name).join('/')
end
def child_folder_paths(*args)
self.class.child_folder_paths(self, *args)
end
def self.child_folder_paths(folder, *args)
options = args.extract_options!
meth = options[:exclude_root_folder] ? :descendants_arranged : :subtree_arranged
subtree = folder.send(meth, :of_type => "EmsFolder")
child_folder_paths_recursive(subtree, options)
end
def self.display_name(number = 1)
n_('Folder', 'Folders', number)
end
# Helper method for building the child folder paths given an arranged subtree.
def self.child_folder_paths_recursive(subtree, options = {})
options[:prefix] ||= ""
subtree.each_with_object({}) do |(f, children), h|
path = options[:prefix]
unless options[:exclude_non_display_folders] && f.hidden?
path = path.blank? ? f.name : "#{path}/#{f.name}"
h[f.id] = path unless options[:exclude_datacenters] && f.kind_of?(Datacenter)
end
h.merge!(child_folder_paths_recursive(children, options.merge(:prefix => path)))
end
end
private_class_method :child_folder_paths_recursive
end