Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chargebacks without rollups :: Fixed metrics for HyperV #13229

Merged
merged 3 commits into from
Dec 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 1 addition & 38 deletions app/models/chargeback/consumption.rb
Original file line number Diff line number Diff line change
@@ -1,48 +1,11 @@
class Chargeback
class Consumption
delegate :timestamp, :resource, :resource_id, :resource_name, :resource_type, :parent_ems,
:hash_features_affecting_rate, :tag_list_with_prefix, :parents_determining_rate,
:to => :first_metric_rollup_record

def initialize(metric_rollup_records, start_time, end_time)
@rollups = metric_rollup_records
def initialize(start_time, end_time)
@start_time, @end_time = start_time, end_time
end

def tag_names
first_metric_rollup_record.tag_names.split('|')
end

def max(metric)
values(metric).max
end

def avg(metric)
metric_sum = values(metric).sum
metric_sum / hours_in_interval
end

def none?(metric)
values(metric).empty?
end

def chargeback_fields_present
@chargeback_fields_present ||= @rollups.count(&:chargeback_fields_present?)
end

def hours_in_interval
@hours_in_interval ||= (@end_time - @start_time).round / 1.hour
end

private

def values(metric)
@values ||= {}
@values[metric] ||= @rollups.collect(&metric.to_sym).compact
end

def first_metric_rollup_record
@fmrr ||= @rollups.first
end
end
end
7 changes: 6 additions & 1 deletion app/models/chargeback/consumption_history.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ def self.for_report(cb_class, options)
timerange = options.report_time_range
interval_duration = options.duration_of_report_step

extra_resources = cb_class.try(:extra_resources_without_rollups) || []
timerange.step_value(interval_duration).each_cons(2) do |query_start_time, query_end_time|
extra_resources.each do |resource|
yield ConsumptionWithoutRollups.new(resource, query_start_time, query_end_time)
end

records = base_rollup.where(:timestamp => query_start_time...query_end_time, :capture_interval_name => 'hourly')
records = cb_class.where_clause(records, options)
records = Metric::Helper.remove_duplicate_timestamps(records)
Expand All @@ -20,7 +25,7 @@ def self.for_report(cb_class, options)
# values are grouped by resource_id and timestamp (query_start_time...query_end_time)
records.group_by(&:resource_id).each do |_, metric_rollup_records|
metric_rollup_records = metric_rollup_records.select { |x| x.resource.present? }
consumption = Consumption.new(metric_rollup_records, query_start_time, query_end_time)
consumption = ConsumptionWithRollups.new(metric_rollup_records, query_start_time, query_end_time)
next if metric_rollup_records.empty?
yield(consumption)
end
Expand Down
44 changes: 44 additions & 0 deletions app/models/chargeback/consumption_with_rollups.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
class Chargeback
class ConsumptionWithRollups < Consumption
delegate :timestamp, :resource, :resource_id, :resource_name, :resource_type, :parent_ems,
:hash_features_affecting_rate, :tag_list_with_prefix, :parents_determining_rate,
:to => :first_metric_rollup_record

def initialize(metric_rollup_records, start_time, end_time)
super(start_time, end_time)
@rollups = metric_rollup_records
end

def tag_names
first_metric_rollup_record.tag_names.split('|')
end

def max(metric)
values(metric).max
end

def avg(metric)
metric_sum = values(metric).sum
metric_sum / hours_in_interval
end

def none?(metric)
values(metric).empty?
end

def chargeback_fields_present
@chargeback_fields_present ||= @rollups.count(&:chargeback_fields_present?)
end

private

def values(metric)
@values ||= {}
@values[metric] ||= @rollups.collect(&metric.to_sym).compact
end

def first_metric_rollup_record
@fmrr ||= @rollups.first
end
end
end
52 changes: 52 additions & 0 deletions app/models/chargeback/consumption_without_rollups.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
class Chargeback
class ConsumptionWithoutRollups < Consumption
delegate :id, :name, :type, :to => :resource, :prefix => :resource
attr_reader :resource

def initialize(resource, start_time, end_time)
super(start_time, end_time)
@resource = resource
end

def timestamp
@start_time
end

def parent_ems
resource.ext_management_system
end

def tag_names
resource.tags.collect(&:name)
end

def hash_features_affecting_rate
resource.id
end

def tag_list_with_prefix
tag_names.map { |t| "vm/tag#{t}" }
end

def parents_determining_rate
[resource.host, resource.ems_cluster, resource.storage, parent_ems, resource.tenant,
MiqEnterprise.my_enterprise].compact
end

def none?(_metric)
true # No, values except for fixed (RateDetail.fixed?)
end

def max(_metric)
raise NotImplementedError # Unreachable code since none?==true
end

def avg(_metric)
raise NotImplementedError # Unreachable code since none?==true
end

def chargeback_fields_present
1 # Yes, charge this interval as fixed_compute_*_*
end
end
end
10 changes: 10 additions & 0 deletions app/models/chargeback_vm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ def self.where_clause(records, options)
end
end

def self.extra_resources_without_rollups
# support hyper-v for which we do not collect metrics yet
scope = ManageIQ::Providers::Microsoft::InfraManager::Vm
if @options[:tag] && (@report_user.nil? || !@report_user.self_service?)
scope.find_tagged_with(:any => @options[:tag], :ns => '*')
else
scope.where(:id => vms)
end
end

def self.report_static_cols
%w(vm_name)
end
Expand Down
38 changes: 34 additions & 4 deletions spec/models/chargeback_vm_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ def used_average_for(metric, hours_in_interval)
:parent_ems_id => ems.id, :parent_storage_id => @storage.id,
:resource => @vm1)
end
let(:consumption) { Chargeback::Consumption.new([metric_rollup], nil, nil) }
let(:consumption) { Chargeback::ConsumptionWithRollups.new([metric_rollup], nil, nil) }

before do
ChargebackRate.set_assignments(:compute, [rate_assignment_options])
Expand All @@ -747,7 +747,7 @@ def used_average_for(metric, hours_in_interval)
let(:timestamp_key) { 'Fri, 13 May 2016 10:40:00 UTC +00:00' }
let(:beginning_of_day) { timestamp_key.in_time_zone.beginning_of_day }
let(:metric_rollup) { FactoryGirl.build(:metric_rollup_vm_hr, :timestamp => timestamp_key, :resource => @vm1) }
let(:consumption) { Chargeback::Consumption.new([metric_rollup], nil, nil) }
let(:consumption) { Chargeback::ConsumptionWithRollups.new([metric_rollup], nil, nil) }
subject { described_class.report_row_key(consumption) }
before do
described_class.instance_variable_set(:@options, report_options)
Expand All @@ -759,7 +759,7 @@ def used_average_for(metric, hours_in_interval)
describe '#initialize' do
let(:report_options) { Chargeback::ReportOptions.new }
let(:vm_owners) { {@vm1.id => @vm1.evm_owner_name} }
let(:consumption) { Chargeback::Consumption.new([metric_rollup], nil, nil) }
let(:consumption) { Chargeback::ConsumptionWithRollups.new([metric_rollup], nil, nil) }
let(:shared_extra_fields) do
{'vm_name' => @vm1.name, 'owner_name' => admin.name, 'vm_uid' => 'ems_ref', 'vm_guid' => @vm1.guid,
'vm_id' => @vm1.id}
Expand Down Expand Up @@ -815,7 +815,7 @@ def used_average_for(metric, hours_in_interval)
:parent_ems_id => ems.id, :parent_storage_id => @storage.id,
:resource => @vm1)
end
let(:consumption) { Chargeback::Consumption.new([metric_rollup], nil, nil) }
let(:consumption) { Chargeback::ConsumptionWithRollups.new([metric_rollup], nil, nil) }

before do
@storage.tag_with([classification_1.tag.name, classification_2.tag.name], :ns => '*')
Expand Down Expand Up @@ -883,4 +883,34 @@ def used_average_for(metric, hours_in_interval)
expect(subject.tag_name).to eq('Production')
end
end

context 'for SCVMM (hyper-v)' do
let!(:vm1) do
vm = FactoryGirl.create(:vm_microsoft)
vm.tag_with(@tag.name, :ns => '*')
vm
end
let(:options) { base_options.merge(:interval => 'daily') }
let(:tier) do
FactoryGirl.create(:chargeback_tier, :start => 0,
:finish => Float::INFINITY,
:fixed_rate => hourly_rate.to_s,
:variable_rate => 0.0)
end
let!(:rate_detail) do
FactoryGirl.create(:chargeback_rate_detail_fixed_compute_cost,
:chargeback_rate_id => @cbr.id,
:chargeback_tiers => [tier],
:per_time => 'hourly')
end

subject { ChargebackVm.build_results_for_report_ChargebackVm(options).first.first }

it 'works' do
expect(subject.chargeback_rates).to eq(@cbr.description)
expect(subject.fixed_compute_metric).to eq(1) # One day of fixed compute metric
expect(subject.fixed_compute_1_cost).to eq(hourly_rate * 24)
expect(subject.total_cost).to eq(hourly_rate * 24)
end
end
end