app/services/ems_physical_infra_dashboard_service.rb
class EmsPhysicalInfraDashboardService < DashboardService
include Mixins::CheckedIdMixin
include TextualMixins::TextualRefreshStatus
include TextualSummaryHelper
def initialize(ems_id, controller)
@ems_id = ems_id
@resource = @ems_id.present? ? Array(find_record_with_rbac(EmsPhysicalInfra, @ems_id)) : EmsPhysicalInfra.all
@controller = controller
end
def aggregate_status_data
{
:aggStatus => aggregate_status
}.compact
end
def recent_servers_data
{
:recentServers => recent_servers
}.compact
end
def aggregate_status
if @ems_id.present?
{
:status => single_provider,
:attrData => attributes_data,
:showTopBorder => false,
:aggregateClass => 'aggregate-object-card',
:aggregateLayout => '',
:refreshStatus => refresh_data,
}
else
{
:status => multiple_providers,
:attrData => attributes_data,
:showTopBorder => true,
:aggregateClass => '',
:aggregateLayout => 'tall',
}
end
end
def refresh_data
{
:last_refresh => refresh_status(@resource.first)
}
end
def servers_group_data
{
:serversGroup => servers_group
}.compact
end
def attributes_data
attributes = %i[physical_chassis
physical_racks
physical_servers
physical_storages
physical_switches]
attr_url = {
:physical_chassis => 'physical_chassis',
:physical_racks => 'physical_rack',
:physical_servers => 'physical_server',
:physical_storages => 'physical_storage',
:physical_switches => 'physical_switch',
}
attr_hsh = {
:physical_chassis => _('Chassis'),
:physical_racks => _('Racks'),
:physical_servers => _('Servers'),
:physical_storages => _('Storages'),
:physical_switches => _('Switches'),
}
attr_data = []
attributes.each do |attr|
attr_notification = []
current_data = {
:id => attr_hsh[attr] + 'Id',
:iconClass => attr.to_s.classify.safe_constantize.try(:decorate).try(:fonticon),
:title => attr_hsh[attr],
:count => 0,
:href => get_url_to_entity(@controller, attr_url[attr], @ems_id, @resource.first),
:notification => {}
}
@resource.each do |ems|
ems_attr = ems.send(attr)
current_data[:count] += ems_attr.length
attr_notification.concat(ems_attr)
end
current_data[:notification] = notification_data(attr_notification, attr_hsh[attr])
attr_data.push(current_data)
end
attr_data
end
def single_provider
{
:iconImage => get_icon(@resource.first),
:largeIcon => true,
}
end
def multiple_providers
providers_data = {
:title => _('Providers'),
:count => 0,
:href => get_url_to_entity(@controller, :ems_physical_infra),
:notifications => {}
}
notification = []
physical_infra_providers = ManageIQ::Providers::PhysicalInfraManager
providers_count = physical_infra_providers.group(:type).count
providers_count.each do |provider, count|
providers_data[:count] += count
notification.push(build_provider_notification(provider, count))
end
providers_data[:notifications] = notification
providers_data
end
def build_provider_notification(provider_namespace, count)
type = provider_namespace.split('::')[2].to_sym
provider = provider_namespace.constantize.new
{
:count => count,
:typeName => _(type),
:iconImage => get_icon(provider),
}
end
def recent_servers
# Get recent servers
all_servers = recent_records(PhysicalServer)
config = {
:title => _('Recent Servers'),
:label => _('Servers')
}
return { :dataAvailable => false, :config => config} if all_servers.blank?
{
:dataAvailable => true,
:xData => all_servers.keys,
:yData => all_servers.values.map,
:config => config
}
end
def notification_data(components, component_type)
if components&.first.respond_to?(:health_state)
count = 0
health_states = components.each_with_object({}) do |component, health_state|
health_state[component.health_state&.downcase] = (health_state[component.health_state&.downcase] || 0) + 1
end
health_states.default = 0
critical_count = health_states["critical"]
warning_count = health_states["warning"]
if critical_count.positive?
icon_class = 'pficon pficon-error-circle-o'
count = critical_count
health_state = 'critical'
elsif warning_count.positive?
icon_class = 'pficon pficon-warning-triangle-o'
count = warning_count
health_state = 'warning'
else
health_state = 'valid'
icon_class = 'pficon pficon-ok'
end
tooltip_count = count.positive? ? count : components.length
{
:count => count,
:iconClass => icon_class,
:tooltip => format_tooltip(health_state, component_type.downcase, tooltip_count),
}
end
end
def format_tooltip(health_state, component_type, count)
tooltip_data = {
:count => count,
:component_type => count > 1 ? component_type : component_type.singularize,
:health_state => health_state,
}
n_(
"%{count} %{component_type} is in %{health_state} state.",
"%{count} %{component_type} are in %{health_state} state.",
count
) % tooltip_data
end
def servers_group
# Get recent Servers
all_servers = Hash.new(0)
servers_with_host = Hash.new(0)
valid_servers = Hash.new(0)
warning_servers = Hash.new(0)
critical_servers = Hash.new(0)
all_physical_servers = PhysicalServer.where('created_at > ?', 30.days.ago.utc)
all_physical_servers = all_physical_servers.where('ems_id = ?', @ems_id) if @ems_id
all_physical_servers.sort_by(&:created_at).each do |server|
date = server.created_at.strftime("%Y-%m-%d")
all_servers[date] += 1
servers_with_host[date] += 1 if server.host.present?
valid_servers[date] += 1 if server.health_state == 'Valid'
warning_servers[date] += 1 if server.health_state == 'Warning'
critical_servers[date] += 1 if server.health_state == 'Critical'
end
format_server_utilization_data(all_servers, valid_servers, warning_servers, critical_servers, servers_with_host)
end
private
def format_server_utilization_data(total_servers, valid_servers, warning_servers, critical_servers, servers_with_host)
{
:availableServers => total_servers.any? ? format_value(total_servers, servers_with_host) : nil,
:serversHealth => total_servers.any? ? format_servers_health(total_servers, valid_servers, warning_servers, critical_servers) : nil,
}
end
def format_value(total, target)
available = check_num(total.values.last) - check_num(target.values.last)
{
:columns => {
:used => check_num(target.values.last),
:available => check_num(available),
},
:xData => total.keys,
:yData => total.values.map,
}
end
def format_servers_health(total_servers, valid_servers, warning_servers, critical_servers)
{
:columns => {
:valid => check_num(valid_servers.values.last),
:warning => check_num(warning_servers.values.last),
:critical => check_num(critical_servers.values.last),
},
:xData => total_servers.keys,
:yData => total_servers.values.map,
}
end
def check_num(val)
(val || 0)
end
def recent_records(model)
all_records = Hash.new(0)
records = model.where('created_at > ?', 30.days.ago.utc)
records = if @ems_id
records.where('ems_id = ?', @ems_id)
else
records.includes(:resource => [:ext_management_system])
end
records.sort_by(&:created_at).uniq.each do |r|
date = r.created_at.strftime("%Y-%m-%d")
all_records[date] += model.where('created_at = ?', r.created_at).count
end
all_records
end
end