Skip to content

Commit

Permalink
move infra targets to metrics capture
Browse files Browse the repository at this point in the history
  • Loading branch information
kbrock committed Jan 6, 2020
1 parent 0e63feb commit 265f8ae
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def filter_perf_capture_now(targets, target_options)
end

def capture_ems_targets(options = {})
Metric::Targets.capture_ems_targets(ems, options)
raise(NotImplementedError, _("must be implemented in subclass"))
end

# if it has not been run, or it was a very long time ago, just run it
Expand Down
1 change: 1 addition & 0 deletions app/models/manageiq/providers/infra_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ class InfraManager < BaseManager
require_nested :Cluster
require_nested :Datacenter
require_nested :Folder
require_nested :MetricsCapture
require_nested :ProvisionWorkflow
require_nested :ResourcePool
require_nested :Storage
Expand Down
97 changes: 96 additions & 1 deletion app/models/manageiq/providers/infra_manager/metrics_capture.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,100 @@
class ManageIQ::Providers::InfraManager::MetricsCapture < ManageIQ::Providers::BaseManager::MetricsCapture
def capture_ems_targets(options = {})
Metric::Targets.capture_infra_targets([ems], options)
capture_infra_targets([ems], options)
end

private

# If a Cluster, standalone Host, or Storage is not enabled, skip it.
# If a Cluster is enabled, capture all of its Hosts.
# If a Host is enabled, capture all of its Vms.
def capture_infra_targets(emses, options)
load_infra_targets_data(emses, options)
all_hosts = capture_host_targets(emses)
targets = enabled_hosts = only_enabled(all_hosts)
targets += capture_storage_targets(all_hosts) unless options[:exclude_storages]
targets += capture_vm_targets(emses, enabled_hosts)

targets
end

# Filter to enabled hosts. If it has a cluster consult that, otherwise consult the host itself.
#
# NOTE: if capture_storage takes only enabled, then move
# this logic into capture_host_targets
def only_enabled(hosts)
hosts.select do |host|
host.supports_capture? && (host.ems_cluster ? host.ems_cluster.perf_capture_enabled? : host.perf_capture_enabled?)
end
end

# preload emses with relations that will be used in cap&u
#
# tags are needed for determining if it is enabled.
# ems is needed for determining queue name
# cluster is used for hierarchies
def load_infra_targets_data(emses, options)
MiqPreloader.preload(emses, preload_hash_infra_targets_data(options))
postload_infra_targets_data(emses, options)
end

def preload_hash_infra_targets_data(options)
# Preload all of the objects we are going to be inspecting.
includes = {:hosts => {:ems_cluster => :tags, :tags => {}}}
includes[:hosts][:storages] = :tags unless options[:exclude_storages]
includes[:vms] = {}
includes
end

# populate parts of the hierarchy that are not properly preloaded
#
# inverse_of does not work with :through.
# e.g.: :ems => :hosts => vms will not preload vms.ems
#
# adding in a preload for vms => :ems will fix, but different objects get assigned
# and since we also rely upon tags and clusters, this causes unnecessary data to be downloaded
#
# so we have introduced this to work around preload not working (and inverse_of)
def postload_infra_targets_data(emses, options)
# populate ems (with tags / clusters)
emses.each do |ems|
ems.hosts.each do |host|
host.ems_cluster.association(:ext_management_system).target = ems if host.ems_cluster_id
unless options[:exclude_storages]
host.storages.each do |storage|
storage.ext_management_system = ems
end
end
end
host_ids = ems.hosts.index_by(&:id)
clusters = ems.hosts.flat_map(&:ems_cluster).uniq.compact.index_by(&:id)
ems.vms.each do |vm|
vm.association(:ext_management_system).target = ems if vm.ems_id
vm.association(:ems_cluster).target = clusters[vm.ems_cluster_id] if vm.ems_cluster_id
vm.association(:host).target = host_ids[vm.host_id] if vm.host_id
end
end
end

def capture_host_targets(emses)
# NOTE: if capture_storage_targets takes only enabled hosts
# merge only_enabled into this method
emses.flat_map(&:hosts)
end

# @param [Host] all hosts that have an ems
# NOTE: disabled hosts are passed in.
# @return [Array<Storage>] supported storages
# hosts preloaded storages and tags
def capture_storage_targets(hosts)
hosts.flat_map(&:storages).uniq.select { |s| Storage.supports?(s.store_type) & s.perf_capture_enabled? }
end

# @param [Array<ExtManagementSystem>] emses Typically 1 ems for this zone
# @param [Host] hosts that are enabled or cluster enabled
# we want to work with only enabled_hosts, so hosts needs to be further filtered
def capture_vm_targets(emses, hosts)
enabled_host_ids = hosts.select(&:perf_capture_enabled?).index_by(&:id)
emses.flat_map { |e| e.vms.select { |v| enabled_host_ids.key?(v.host_id) && v.state == 'on' && v.supports_capture? } }
end
end
99 changes: 0 additions & 99 deletions app/models/metric/targets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,103 +12,4 @@ def self.targets_archived_from
archived_for_setting = Settings.performance.targets.archived_for
archived_for_setting.to_i_with_method.seconds.ago.utc
end

def self.capture_ems_targets(ems, options = {})
case ems
when EmsInfra then capture_infra_targets([ems], options)
end
end

# If a Cluster, standalone Host, or Storage is not enabled, skip it.
# If a Cluster is enabled, capture all of its Hosts.
# If a Host is enabled, capture all of its Vms.
def self.capture_infra_targets(emses, options)
load_infra_targets_data(emses, options)
all_hosts = capture_host_targets(emses)
targets = enabled_hosts = only_enabled(all_hosts)
targets += capture_storage_targets(all_hosts) unless options[:exclude_storages]
targets += capture_vm_targets(emses, enabled_hosts)

targets
end

# Filter to enabled hosts. If it has a cluster consult that, otherwise consult the host itself.
#
# NOTE: if capture_storage takes only enabled, then move
# this logic into capture_host_targets
def self.only_enabled(hosts)
hosts.select do |host|
host.supports_capture? && (host.ems_cluster ? host.ems_cluster.perf_capture_enabled? : host.perf_capture_enabled?)
end
end

# preload emses with relations that will be used in cap&u
#
# tags are needed for determining if it is enabled.
# ems is needed for determining queue name
# cluster is used for hierarchies
def self.load_infra_targets_data(emses, options)
MiqPreloader.preload(emses, preload_hash_infra_targets_data(options))
postload_infra_targets_data(emses, options)
end

def self.preload_hash_infra_targets_data(options)
# Preload all of the objects we are going to be inspecting.
includes = {:hosts => {:ems_cluster => :tags, :tags => {}}}
includes[:hosts][:storages] = :tags unless options[:exclude_storages]
includes[:vms] = {}
includes
end

# populate parts of the hierarchy that are not properly preloaded
#
# inverse_of does not work with :through.
# e.g.: :ems => :hosts => vms will not preload vms.ems
#
# adding in a preload for vms => :ems will fix, but different objects get assigned
# and since we also rely upon tags and clusters, this causes unnecessary data to be downloaded
#
# so we have introduced this to work around preload not working (and inverse_of)
def self.postload_infra_targets_data(emses, options)
# populate ems (with tags / clusters)
emses.each do |ems|
ems.hosts.each do |host|
host.ems_cluster.association(:ext_management_system).target = ems if host.ems_cluster_id
unless options[:exclude_storages]
host.storages.each do |storage|
storage.ext_management_system = ems
end
end
end
host_ids = ems.hosts.index_by(&:id)
clusters = ems.hosts.flat_map(&:ems_cluster).uniq.compact.index_by(&:id)
ems.vms.each do |vm|
vm.association(:ext_management_system).target = ems if vm.ems_id
vm.association(:ems_cluster).target = clusters[vm.ems_cluster_id] if vm.ems_cluster_id
vm.association(:host).target = host_ids[vm.host_id] if vm.host_id
end
end
end

def self.capture_host_targets(emses)
# NOTE: if capture_storage_targets takes only enabled hosts
# merge only_enabled into this method
emses.flat_map(&:hosts)
end

# @param [Host] all hosts that have an ems
# NOTE: disabled hosts are passed in.
# @return [Array<Storage>] supported storages
# hosts preloaded storages and tags
def self.capture_storage_targets(hosts)
hosts.flat_map(&:storages).uniq.select { |s| Storage.supports?(s.store_type) & s.perf_capture_enabled? }
end

# @param [Array<ExtManagementSystem>] emses Typically 1 ems for this zone
# @param [Host] hosts that are enabled or cluster enabled
# we want to work with only enabled_hosts, so hosts needs to be further filtered
def self.capture_vm_targets(emses, hosts)
enabled_host_ids = hosts.select(&:perf_capture_enabled?).index_by(&:id)
emses.flat_map { |e| e.vms.select { |v| enabled_host_ids.key?(v.host_id) && v.state == 'on' && v.supports_capture? } }
end
end

0 comments on commit 265f8ae

Please sign in to comment.