app/controllers/chargeback_assignment_controller.rb
class ChargebackAssignmentController < ApplicationController
before_action :check_privileges
before_action :get_session_data
after_action :cleanup_action
after_action :set_session_data
include Mixins::GenericSessionMixin
include Mixins::BreadcrumbsMixin
def self.table_name
@table_name ||= "chargeback_assignment"
end
def index
assert_privileges("chargeback_assignments")
@tabform = ChargebackRate::VALID_CB_RATE_TYPES.include?(params[:tab]) ? params[:tab] : "Compute"
session[:changed] = @changed = false
build_tabs
set_form_vars
end
def change_tab
assert_privileges("chargeback_assignments")
clear_flash_msg
@tabform = params['uib-tab']
build_tabs
set_form_vars
render :action => "index"
end
# AJAX driven routine to check for changes in ANY field on the form
def form_field_changed
assert_privileges("chargeback_assignments")
return unless load_edit("cbassign_edit__#{params[:id]}", "index")
get_form_vars
build_tabs
render :update do |page|
page << javascript_prologue
except = %i[cbshow_typ cbtag_cat cblabel_key]
changed = (@edit[:new].except(*except) != @edit[:current].except(*except))
page.replace(@edit[:new][:type], :partial => "#{@edit[:new][:type].downcase}_assignments") if params[:cbshow_typ] || params[:cbtag_cat] || params[:cblabel_key]
page << javascript_for_miq_button_visibility(changed)
end
end
def update
assert_privileges("chargeback_assignments")
clear_flash_msg
return unless load_edit("cbassign_edit__#{params[:id]}", "index")
case params[:button]
when "reset"
flash_to_session(_("All changes have been reset"), :warning)
when "save"
set_record_vars
rate_type = params[:id]
begin
ChargebackRate.set_assignments(rate_type, @edit[:set_assignments])
rescue StandardError => bang
render_flash(_("Error during 'Rate assignments': %{error_message}") % {:error_message => bang.message}, :error)
else
flash_to_session(_("Rate Assignments saved"))
end
end
set_form_vars
build_tabs
render :update do |page|
page << javascript_prologue
page.replace(@edit[:new][:type], :partial => "#{@edit[:new][:type].downcase}_assignments")
end
end
private ############################
def build_tabs
@breadcrumbs = []
@title = _("Chargeback Assignments")
@active_tab = @tabform
@tabs = [["Compute", _("Compute")], ["Storage", _("Storage")]]
end
# Set record vars for save
def set_record_vars
@edit[:set_assignments] = []
if @edit[:new][:cbshow_typ].ends_with?("-tags")
assigned_rates_from_all_categories = @edit[:cb_assign][:tags].values.reduce({}, :merge)
assigned_rates_from_all_categories.each_key do |id|
key = "#{@edit[:new][:cbshow_typ]}__#{id}"
next if @edit[:new][key].nil? || @edit[:new][key] == "nil"
temp = {
:cb_rate => ChargebackRate.find(@edit[:new][key]),
:tag => [Classification.find(id)],
}
temp[:tag].push(@edit[:new][:cbshow_typ].split("-").first)
@edit[:set_assignments].push(temp)
end
elsif @edit[:new][:cbshow_typ].ends_with?("-labels")
@edit[:cb_assign][:docker_label_values_saved].each_key do |id|
key = "#{@edit[:new][:cbshow_typ]}__#{id}"
next if @edit[:new][key].nil? || @edit[:new][key] == "nil"
temp = {
:cb_rate => ChargebackRate.find(@edit[:new][key]),
:label => [CustomAttribute.find(id)]
}
temp[:label].push(@edit[:new][:cbshow_typ].split("-").first)
@edit[:set_assignments].push(temp)
end
else
@edit[:cb_assign][:cis].each_key do |id|
key = "#{@edit[:new][:cbshow_typ]}__#{id}"
next if @edit[:new][key].nil? || @edit[:new][key] == "nil"
temp = {:cb_rate => ChargebackRate.find(@edit[:new][key])}
model = if @edit[:new][:cbshow_typ] == "enterprise"
MiqEnterprise
elsif @edit[:new][:cbshow_typ] == "ems_container"
ExtManagementSystem
else
Object.const_get(@edit[:new][:cbshow_typ].camelize) rescue nil
end
temp[:object] = model.find(id) unless model.nil?
@edit[:set_assignments].push(temp)
end
end
end
# Set form variables for edit, once user has made type selection
def set_form_vars
@edit = {
:cb_rates => {},
:cb_assign => {},
}
@edit[:new] = HashWithIndifferentAccess.new
@edit[:current] = HashWithIndifferentAccess.new
@edit[:new][:type] = params[:id] && ChargebackRate::VALID_CB_RATE_TYPES.include?(params[:id]) ? params[:id] : @tabform
@edit[:key] = "cbassign_edit__#{@edit[:new][:type]}"
ChargebackRate.all.each do |cbr|
if cbr.rate_type == @edit[:new][:type]
@edit[:cb_rates][cbr.id.to_s] = cbr.description
end
end
@edit[:current_assignment] = ChargebackRate.get_assignments(@edit[:new][:type])
unless @edit[:current_assignment].empty?
@edit[:new][:cbshow_typ] = case @edit[:current_assignment][0][:object]
when EmsCluster
"ems_cluster"
when ExtManagementSystem, ManageIQ::Providers::ContainerManager
"ext_management_system"
when MiqEnterprise
"enterprise"
when NilClass
if @edit[:current_assignment][0][:tag]
"#{@edit[:current_assignment][0][:tag][1]}-tags"
else
"#{@edit[:current_assignment][0][:label][1]}-labels"
end
else
if @edit[:current_assignment][0][:object].class.name.split("::").last.downcase == "storage"
"storage"
else
@edit[:current_assignment][0][:object].class.name.downcase
end
end
end
if @edit[:new][:cbshow_typ]&.ends_with?("-tags")
get_categories_all
tag = @edit[:current_assignment][0][:tag][0]
if tag
@edit[:new][:cbtag_cat] = tag["parent_id"].to_s
get_tags_all
else
@edit[:current_assignment] = []
end
elsif @edit[:new][:cbshow_typ]&.ends_with?("-labels")
get_docker_labels_all_keys
assigned_label = @edit[:current_assignment][0][:label][0]
if assigned_label
label = @edit[:cb_assign][:docker_label_keys].detect { |_key, value| value == assigned_label.name }
label ||= @edit[:cb_assign][:docker_label_default_keys].detect { |_key, value| value == assigned_label.name }
@edit[:new][:cblabel_key] = label.first
get_docker_labels_all_values(label.first)
else
@edit[:current_assignment] = []
end
elsif @edit[:new][:cbshow_typ]
get_cis_all
end
@edit[:current_assignment].each do |el|
if el[:object]
@edit[:new]["#{@edit[:new][:cbshow_typ]}__#{el[:object]["id"]}"] = el[:cb_rate]["id"].to_s
elsif el[:tag]
@edit[:new]["#{@edit[:new][:cbshow_typ]}__#{el[:tag][0]["id"]}"] = el[:cb_rate]["id"].to_s
elsif el[:label]
@edit[:new]["#{@edit[:new][:cbshow_typ]}__#{el[:label][0].id}"] = el[:cb_rate]["id"].to_s
end
end
@edit[:current] = copy_hash(@edit[:new])
session[:edit] = @edit
@in_a_form = true
end
def get_categories_all
@edit[:cb_assign][:cats] = {}
Classification.categories.select { |c| c.show && !c.entries.empty? }.each do |c|
@edit[:cb_assign][:cats][c.id.to_s] = c.description
end
end
def get_tags_all
@edit[:cb_assign][:tags] ||= {}
Classification.all.each do |category|
@edit[:cb_assign][:tags][category.id] ||= {}
category.entries.each do |entry|
@edit[:cb_assign][:tags][category.id][entry.id.to_s] = entry.description
end
end
end
DEFAULT_CHARGEBACK_LABELS = ["com.redhat.component"].freeze
def get_docker_labels_all_keys
@edit[:cb_assign][:docker_label_keys] = {}
@edit[:cb_assign][:docker_label_default_keys] = {}
CustomAttribute.where(:section => "docker_labels").pluck(:id, :name).uniq(&:second).each do |label|
if DEFAULT_CHARGEBACK_LABELS.include?(label.second)
@edit[:cb_assign][:docker_label_default_keys][label.first.to_s] = label.second
else
@edit[:cb_assign][:docker_label_keys][label.first.to_s] = label.second
end
end
end
def get_docker_labels_all_values(label_id)
@edit[:cb_assign][:docker_label_values] = {}
@edit[:cb_assign][:docker_label_values_saved] = {}
CustomAttribute.where(:section => "docker_labels").pluck(:id, :value).each do |label|
@edit[:cb_assign][:docker_label_values_saved][label.first.to_s] = label.second
end
return if label_id && label_id == 'null' || label_id.nil?
label_name = CustomAttribute.find(label_id).name
CustomAttribute.where(:section => "docker_labels", :name => label_name).pluck(:id, :value).uniq(&:second).each do |label|
@edit[:cb_assign][:docker_label_values][label.first.to_s] = label.second
end
end
WHITELIST_INSTANCE_TYPE = %w[enterprise storage ext_management_system ems_cluster tenant ems_container].freeze
NOTHING_FORM_VALUE = "nil".freeze
def get_cis_all
@edit[:cb_assign][:cis] = {}
klass = @edit[:new][:cbshow_typ]
return if klass == NOTHING_FORM_VALUE || klass.nil? # no rate was selected
unless WHITELIST_INSTANCE_TYPE.include?(klass)
raise ArgumentError, "Received: #{klass}, expected one of #{WHITELIST_INSTANCE_TYPE}"
end
all_of_classtype =
if klass == "enterprise"
MiqEnterprise.all
elsif klass == "ext_management_system"
ExtManagementSystem.all
else
klass.classify.constantize.all
end
@edit[:cb_assign][:hierarchy] ||= {}
all_of_classtype.each do |instance|
@edit[:cb_assign][:cis][instance.id] = instance.name
if klass == "ems_cluster"
provider_name = instance.ext_management_system.name
@edit[:cb_assign][:cis][instance.id] = "#{provider_name}/#{instance.name}"
end
next unless klass == "tenant" && instance.root?
@edit[:cb_assign][:hierarchy][instance.id] = {}
@edit[:cb_assign][:hierarchy][instance.id][:name] = instance.name
@edit[:cb_assign][:hierarchy][instance.id][:subtenant] = instance.build_tenant_tree
end
end
def params_to_edit(cb_assign_key, tag_category_id = nil)
current_assingments = cb_assign_key == :tags ? @edit[:cb_assign][cb_assign_key].try(:[], tag_category_id) : @edit[:cb_assign][cb_assign_key]
return unless current_assingments
current_assingments.each_key do |id|
key = "#{@edit[:new][:cbshow_typ]}__#{id}"
@edit[:new][key] = params[key].to_s if params[key]
end
end
# Get variables from edit form
def get_form_vars
@edit[:new][:cbshow_typ] = params[:cbshow_typ] if params[:cbshow_typ]
@edit[:new][:cbtag_cat] = nil if params[:cbshow_typ] # Reset categories pull down if assign to selection is changed
@edit[:new][:cbtag_cat] = params[:cbtag_cat].to_s if params[:cbtag_cat]
@edit[:new][:cblabel_key] = nil if params[:cbshow_typ]
@edit[:new][:cblabel_key] = params[:cblabel_key].to_s if params[:cblabel_key]
if @edit[:new][:cbshow_typ].ends_with?("-tags")
get_categories_all
get_tags_all
elsif @edit[:new][:cbshow_typ].ends_with?("-labels")
get_docker_labels_all_keys
get_docker_labels_all_values(@edit[:new][:cblabel_key])
else
get_cis_all
end
params_to_edit(:cis)
params_to_edit(:tags, @edit[:new][:cbtag_cat].try(:to_i))
params_to_edit(:docker_label_values)
end
def breadcrumbs_options
{
:breadcrumbs => [
{:title => _("Overview")},
{:title => _("Chargeback")},
{:title => _("Assignments"), :url => controller_url},
],
}
end
menu_section :chargeback
end