app/controllers/utilization_controller.rb
class UtilizationController < ApplicationController
before_action :check_privileges
before_action :get_session_data
menu_section(:vi)
include OptimizeHelper
include Mixins::BreadcrumbsMixin
def index
assert_privileges('utilization')
@explorer = true
@right_cell_text = _("Utilization Summary")
@sb[:active_tab] = "summary"
@sb[:options] = {} # reset existing values
build_accordions_and_trees
get_time_profiles # Get time profiles list (global and user specific)
# Get the time zone from the time profile, if one is in use
if @sb[:options][:time_profile]
tp = TimeProfile.find_by(:id => @sb[:options][:time_profile])
set_time_profile_vars(tp, @sb[:options])
else
set_time_profile_vars(selected_time_profile_for_pull_down, @sb[:options])
end
@ajax_action = "chart_chooser"
render :layout => "application"
end
# Process changes to capacity charts
def chart_chooser
assert_privileges('utilization')
unless params[:task_id] # Only do this first time thru
@sb[:options][:chart_date] = params[:miq_date_1] if params[:miq_date_1]
@sb[:options][:chart_date] = params[:miq_date_2] if params[:miq_date_2]
@sb[:options][:days] = params[:details_days] if params[:details_days]
@sb[:options][:days] = params[:report_days] if params[:report_days]
@sb[:options][:days] = params[:summ_days] if params[:summ_days]
@sb[:options][:tz] = params[:details_tz] if params[:details_tz]
@sb[:options][:tz] = params[:report_tz] if params[:report_tz]
@sb[:options][:tz] = params[:summ_tz] if params[:summ_tz]
@sb[:options][:tag] = params[:details_tag] == "<None>" ? nil : params[:details_tag] if params[:details_tag]
@sb[:options][:tag] = params[:report_tag] == "<None>" ? nil : params[:report_tag] if params[:report_tag]
@sb[:options][:tag] = params[:summ_tag] == "<None>" ? nil : params[:summ_tag] if params[:summ_tag]
@sb[:options][:index] = params[:chart_idx] == "clear" ? nil : params[:chart_idx] if params[:chart_idx]
if params.key?(:details_time_profile) || params.key?(:report_time_profile) || params.key?(:summ_time_profile)
@sb[:options][:time_profile] = params[:details_time_profile].blank? ? nil : params[:details_time_profile].to_i if params.key?(:details_time_profile)
@sb[:options][:time_profile] = params[:report_time_profile].blank? ? nil : params[:report_time_profile].to_i if params.key?(:report_time_profile)
@sb[:options][:time_profile] = params[:summ_time_profile].blank? ? nil : params[:summ_time_profile].to_i if params.key?(:summ_time_profile)
tp = TimeProfile.find(@sb[:options][:time_profile]) if @sb[:options][:time_profile].present?
@sb[:options][:time_profile_tz] = @sb[:options][:time_profile].blank? ? nil : tp.tz
@sb[:options][:time_profile_days] = @sb[:options][:time_profile].blank? ? nil : tp.days
end
end
if x_node != ""
get_node_info(x_node, "n")
perf_util_daily_gen_data("n")
end
@right_cell_text ||= _("Utilization Summary")
replace_right_cell(@nodetype) unless @waiting # Draw right side if task is done
end
# Send the current utilization report data in text, CSV, or PDF
def report_download
assert_privileges('utilization')
report = MiqReport.new(:title => @sb[:title],
:cols => cols = %w[section item value],
:col_order => cols,
:headers => [_("Section"), _("Item"), _("Value")],
:sortby => ["section"],
:extras => {},
:group => "y")
report.db = "MetricRollup"
report.table = ManageIQ::Reporting::Formatter::Converter.hashes2table(summ_hashes, :only => report.cols)
filename = report.title
disable_client_cache
download_file(params[:typ], report, filename)
end
def tree_select
assert_accordion_and_tree_privileges(x_active_tree)
if params[:id] # First time thru async method, grab id parm info
@refresh = (x_node == "")
self.x_node = params[:id]
end
@sb[:options][:tag] = nil # Reset any tag
get_node_info(x_node)
perf_util_daily_gen_data
replace_right_cell(@nodetype) unless @waiting # Draw right side if task is done
end
def change_tab
assert_privileges('utilization')
@sb[:active_tab] = params[:tab_id]
# build timeline data when coming back to Summary tab
render :update do |page|
page << javascript_prologue
page << javascript_reload_toolbars
page << ManageIQ::Reporting::Charting.js_load_statement
page << "miqSparkle(false);"
end
end
private
def features
[
{
:role => "utilization",
:role_any => true,
:name => :utilization,
:title => _("Utilization")
}
].map { |hsh| ApplicationController::Feature.new_with_hash(hsh) }
end
def get_session_data
@title = _("Utilization")
@layout ||= "miq_capacity_utilization"
end
# Get all info for the node about to be displayed
def get_node_info(treenodeid, refresh = nil)
treenodeid = valid_active_node(treenodeid)
get_nodetype_and_record(treenodeid)
@right_cell_text = if @record.kind_of?(MiqEnterprise)
_('Enterprise')
else
_("%{model} \"%{name}\" Utilization Trend Summary") %
{:model => ui_lookup(:model => @record.class.base_class.to_s), :name => @record.name}
end
@sb[:title] = @right_cell_text
unless @sb[:options].nil? || @sb[:options][:tag].blank?
@right_cell_text += _(" - Filtered by %{filter}") % {:filter => @sb[:tags][@sb[:options][:tag]]}
end
# Get start/end dates in selected timezone
tz = @sb[:options][:time_profile_tz] || @sb[:options][:tz] # Use time profile tz or chosen tz, if no profile tz
s, e = @record.first_and_last_capture
return if s.nil?
s = s.in_time_zone(tz)
e = e.in_time_zone(tz)
# Eliminate partial start or end days
s = s.hour.zero? ? s : s + 1.day
e = e.hour < 23 ? e - 1.day : e
return if s > e # Don't have a full day's data
sdate = create_time_in_tz("#{s.year}-#{s.month}-#{s.day} 00", tz) # Start at midnight of start date
edate = create_time_in_tz("#{e.year}-#{e.month}-#{e.day} 23", tz) # End at 11pm of start date
unless (refresh == "n" || params[:refresh] == "n") && @sb[:options] && @sb[:options][:model] == @record.class.base_class.to_s
@sb[:options] ||= {}
@sb[:options][:typ] = "Daily"
@sb[:options][:days] ||= "7"
@sb[:options][:model] = @record.class.base_class.to_s
@sb[:options][:record_id] = @record.id
end
trenddate = edate - @sb[:options][:days].to_i.days + 1.hour # Get trend starting date
sdate = sdate > trenddate ? sdate : trenddate # Use trend date, unless earlier than first date
if @sb[:options][:chart_date] # Clear chosen chart date if out of trend range
cdate = create_time_in_tz(@sb[:options][:chart_date], tz) # Get chart date at midnight in time zone
if (cdate < sdate || cdate > edate) || # Reset if chart date is before start date or after end date
(@sb[:options][:time_profile] && !@sb[:options][:time_profile_days].include?(cdate.wday))
@sb[:options][:chart_date] = nil
end
end
@sb[:options][:trend_start] = sdate
@sb[:options][:trend_end] = edate
@sb[:options][:sdate] = sdate # Start and end dates for calendar control
@sb[:options][:edate] = edate
@sb[:options][:chart_date] ||= [edate.month, edate.day, edate.year].join("/")
if @sb[:options][:time_profile] # If profile in effect, set date to a valid day in the profile
@sb[:options][:skip_days] = skip_days_from_time_profile(@sb[:options][:time_profile_days])
cdate = @sb[:options][:chart_date].to_date # Start at the currently set date
6.times do # Go back up to 6 days (try each weekday)
break if @sb[:options][:time_profile_days].include?(cdate.wday) # If weekday is in the profile, use it
cdate -= 1.day # Drop back 1 day and try again
end
@sb[:options][:chart_date] = [cdate.month, cdate.day, cdate.year].join("/") # Set the new date
else
@sb[:options][:skip_days] = nil
end
@sb[:options][:days] ||= "7"
@sb[:options][:ght_type] ||= "hybrid"
@sb[:options][:chart_type] = :summary
end
# replace_trees can be an array of tree symbols to be replaced
def replace_right_cell(_nodetype)
# Get the tags for this node for the Classification pulldown
@sb[:tags] = nil unless params[:miq_date_1] || params[:miq_date_2] # Clear tags unless just changing date
unless @nodetype == "h" || @nodetype == "s" || params[:miq_date_1] || params[:miq_date_2] # Get the tags for the pulldown, unless host, storage, or just changing the date
if @sb[:options][:chart_date]
mm, dd, yy = @sb[:options][:chart_date].split("/")
end_date = Time.utc(yy, mm, dd, 23, 59, 59)
@sb[:tags] = VimPerformanceAnalysis.child_tags_over_time_period(
@record, 'daily',
:end_date => end_date, :days => @sb[:options][:days].to_i,
:ext_options => {:tz => @sb[:trend_rpt].tz, # Add ext_options for tz from rpt object
:time_profile => @sb[:trend_rpt].time_profile}
)
end
end
v_tb = build_toolbar("miq_capacity_view_tb")
presenter = ExplorerPresenter.new(:active_tree => x_active_tree)
presenter.load_chart(@sb[:chart_data])
# clearing out any selection in tree if active node has been reset to "" upon returning to screen or when first time in
presenter[:clear_selection] = x_node == ''
presenter.reload_toolbars(:view => v_tb)
presenter.update(:main_div, r[:partial => 'utilization_tabs'])
presenter.update(:breadcrumbs, r[:partial => 'layouts/breadcrumbs'])
presenter[:right_cell_text] = @right_cell_text
presenter[:build_calendar] = {
:date_from => @sb[:options][:sdate],
:date_to => @sb[:options][:edate],
:skip_days => @sb[:options][:skip_days],
}
render :json => presenter.for_render
end
# Create an array of hashes from the Utilization summary report tab information
def summ_hashes
a = []
@sb[:summary][:info]&.each { |r| a.push("section" => _("Basic Info"), "item" => r[0], "value" => r[1]) }
@sb[:summary][:cpu]&.each { |r| a.push("section" => _("CPU"), "item" => r[0], "value" => r[1]) }
@sb[:summary][:memory]&.each { |r| a.push("section" => _("Memory"), "item" => r[0], "value" => r[1]) }
@sb[:summary][:storage]&.each { |r| a.push("section" => _("Disk"), "item" => r[0], "value" => r[1]) }
a
end
def breadcrumbs_options
{
:breadcrumbs => [
{:title => _("Overview")},
{:title => _("Utilization")},
],
}
end
end