Skip to content

Commit

Permalink
Charge for container limits in ChargebackContainerImage
Browse files Browse the repository at this point in the history
  • Loading branch information
Ari Zellner committed Oct 29, 2017
1 parent 44eb788 commit 9767bea
Show file tree
Hide file tree
Showing 12 changed files with 113 additions and 36 deletions.
2 changes: 1 addition & 1 deletion app/models/chargeable_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def showback_dimension
def measure(consumption, options, sub_metric = nil)
return consumption.consumed_hours_in_interval if metering?
return 1.0 if fixed?
return 0 if consumption.none?(metric)
return 0 if options.method_for_allocated_metrics != :current_value && consumption.none?(metric)
return consumption.send(options.method_for_allocated_metrics, metric, sub_metric) if allocated?
return consumption.avg(metric) if used?
end
Expand Down
9 changes: 9 additions & 0 deletions app/models/chargeback/consumption_with_rollups.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ def avg(metric, sub_metric = nil)
metric_sum / consumed_hours_in_interval
end

def current_value(metric, _sub_metric) # used for containers allocated metrics
case metric
when 'derived_vm_numvcpu_cores' # Allocated CPU count
resource.try(:limit_cpu_cores).to_f
when 'derived_memory_available'
resource.try(:limit_memory_bytes).to_f / 1.megabytes # bytes to megabytes
end
end

def none?(metric)
values(metric).empty?
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/chargeback/rates_cache.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def rates(consumption)
:tag_list => consumption.tag_list_with_prefix,
:parents => consumption.parents_determining_rate)

if consumption.resource_type == Container.name && rates.empty?
if consumption.resource.kind_of?(Container) && rates.empty?
rates = [ChargebackRate.find_by(:description => "Default Container Image Rate", :rate_type => "Compute")]
end

Expand Down
2 changes: 1 addition & 1 deletion app/models/chargeback/report_options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def self.new_from_h(hash)
new(*hash.values_at(*members))
end

ALLOCATED_METHODS_WHITELIST = %i(max avg).freeze
ALLOCATED_METHODS_WHITELIST = %i(max avg current_value).freeze

def method_for_allocated_metrics
method = self[:method_for_allocated_metrics] || :max
Expand Down
68 changes: 38 additions & 30 deletions app/models/chargeback_container_image.rb
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
class ChargebackContainerImage < Chargeback
set_columns_hash(
:project_name => :string,
:image_name => :string,
:project_uid => :string,
:provider_name => :string,
:provider_uid => :string,
:archived => :string,
:cpu_cores_used_cost => :float,
:cpu_cores_used_metric => :float,
:fixed_compute_1_cost => :float,
:fixed_compute_2_cost => :float,
:fixed_2_cost => :float,
:fixed_cost => :float,
:memory_used_cost => :float,
:memory_used_metric => :float,
:net_io_used_cost => :float,
:net_io_used_metric => :float,
:total_cost => :float,
:project_name => :string,
:image_name => :string,
:project_uid => :string,
:provider_name => :string,
:provider_uid => :string,
:archived => :string,
:cpu_cores_used_cost => :float,
:cpu_cores_used_metric => :float,
:cpu_cores_allocated_metric => :float,
:cpu_cores_allocated_cost => :float,
:fixed_compute_1_cost => :float,
:fixed_compute_2_cost => :float,
:fixed_cost => :float,
:memory_used_cost => :float,
:memory_used_metric => :float,
:memory_allocated_cost => :float,
:memory_allocated_metric => :float,
:net_io_used_cost => :float,
:net_io_used_metric => :float,
:total_cost => :float,
)

def self.build_results_for_report_ChargebackContainerImage(options)
Expand Down Expand Up @@ -48,6 +51,7 @@ def self.build_results_for_report_ChargebackContainerImage(options)
@unknown_image ||= OpenStruct.new(:id => 0, :full_name => _('Unknown Image'))

load_custom_attribute_groupby(options[:groupby_label]) if options[:groupby_label].present?
options[:method_for_allocated_metrics] = :current_value
build_results_for_report_chargeback(options)
ensure
@data_index = @containers = nil
Expand Down Expand Up @@ -89,19 +93,23 @@ def self.report_static_cols

def self.report_col_options
{
"cpu_cores_used_cost" => {:grouping => [:total]},
"cpu_cores_used_metric" => {:grouping => [:total]},
"fixed_compute_metric" => {:grouping => [:total]},
"fixed_compute_1_cost" => {:grouping => [:total]},
"fixed_compute_2_cost" => {:grouping => [:total]},
"fixed_cost" => {:grouping => [:total]},
"memory_used_cost" => {:grouping => [:total]},
"memory_used_metric" => {:grouping => [:total]},
"metering_used_metric" => {:grouping => [:total]},
"metering_used_cost" => {:grouping => [:total]},
"net_io_used_cost" => {:grouping => [:total]},
"net_io_used_metric" => {:grouping => [:total]},
"total_cost" => {:grouping => [:total]}
"cpu_cores_used_cost" => {:grouping => [:total]},
"cpu_cores_used_metric" => {:grouping => [:total]},
"cpu_cores_allocated_metric" => {:grouping => [:total]},
"cpu_cores_allocated_cost" => {:grouping => [:total]},
"fixed_compute_metric" => {:grouping => [:total]},
"fixed_compute_1_cost" => {:grouping => [:total]},
"fixed_compute_2_cost" => {:grouping => [:total]},
"fixed_cost" => {:grouping => [:total]},
"memory_used_cost" => {:grouping => [:total]},
"memory_used_metric" => {:grouping => [:total]},
"metering_used_metric" => {:grouping => [:total]},
"metering_used_cost" => {:grouping => [:total]},
"memory_allocated_cost" => {:grouping => [:total]},
"memory_allocated_metric" => {:grouping => [:total]},
"net_io_used_cost" => {:grouping => [:total]},
"net_io_used_metric" => {:grouping => [:total]},
"total_cost" => {:grouping => [:total]}
}
end

Expand Down
4 changes: 4 additions & 0 deletions db/fixtures/chargeable_fields.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
:description: Allocated CPU Count
:group: cpu
:source: allocated
- :metric: derived_vm_numvcpu_cores
:description: Allocated CPU Cores
:group: cpu_cores
:source: allocated
- :metric: derived_memory_used
:description: Used Memory
:group: memory
Expand Down
20 changes: 20 additions & 0 deletions db/fixtures/chargeback_rates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@
:finish: Infinity
:fixed_rate: 1.0
:variable_rate: 0.0
- :description: Allocated CPU Cores
:metric: derived_vm_numvcpu_cores
:per_time: hourly
:per_unit: cpu core
:type_currency: Dollars
:tiers:
- :start: 0
:finish: Infinity
:fixed_rate: 1.0
:variable_rate: 0.0
- :description: Used Memory
:metric: derived_memory_used
:per_time: hourly
Expand Down Expand Up @@ -184,6 +194,16 @@
:finish: Infinity
:fixed_rate: 1.0
:variable_rate: 0.0
- :description: Allocated CPU Cores
:metric: derived_vm_numvcpu_cores
:per_time: hourly
:per_unit: cpu core
:type_currency: Dollars
:tiers:
- :start: 0
:finish: Infinity
:fixed_rate: 1.0
:variable_rate: 0.0
- :description: Used Memory
:metric: derived_memory_used
:per_time: hourly
Expand Down
2 changes: 2 additions & 0 deletions db/fixtures/miq_report_formats.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
:cpu_cores_used_cost: :currency_precision_2
:cpu_allocated_cost: :currency_precision_2
:cpu_allocated_metric: :general_number_precision_0
:cpu_cores_allocated_cost: :currency_precision_2
:cpu_cores_allocated_metric: :general_number_precision_0
:cpu_cost: :currency_precision_2
:memory_used_cost: :currency_precision_2
:memory_allocated_cost: :currency_precision_2
Expand Down
7 changes: 7 additions & 0 deletions spec/factories/chargeable_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@
source 'used'
end

factory :chargeable_field_cpu_cores_allocated, :parent => :chargeable_field do
description 'Allocated CPU in Cores'
metric 'derived_vm_numvcpu_cores'
group 'cpu_cores'
source 'allocated'
end

factory :chargeable_field_memory_used, :parent => :chargeable_field do
description 'Used Memory in MB'
metric 'derived_memory_used'
Expand Down
5 changes: 5 additions & 0 deletions spec/factories/chargeback_rate_detail.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@
chargeable_field { FactoryGirl.build(:chargeable_field_cpu_cores_used) }
end

factory :chargeback_rate_detail_cpu_cores_allocated, :parent => :chargeback_rate_detail do
per_unit "cores"
chargeable_field { FactoryGirl.build(:chargeable_field_cpu_cores_allocated) }
end

factory :chargeback_rate_detail_cpu_allocated, :traits => [:daily],
:parent => :chargeback_rate_detail do
per_unit "cpu"
Expand Down
27 changes: 24 additions & 3 deletions spec/models/chargeback_container_image_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

let(:base_options) { {:interval_size => 2, :end_interval_offset => 0, :ext_options => {:tz => 'UTC'} } }
let(:hourly_rate) { 0.01 }
let(:count_hourly_rate) { 1.00 }
let(:starting_date) { Time.parse('2012-09-01 23:59:59Z').utc }
let(:ts) { starting_date.in_time_zone(Metric::Helper.get_time_zone(options[:ext_options])) }
let(:report_run_time) { month_end }
Expand All @@ -13,11 +14,14 @@
let(:ems) { FactoryGirl.create(:ems_openshift) }

let(:hourly_variable_tier_rate) { {:variable_rate => hourly_rate.to_s} }
let(:count_hourly_variable_tier_rate) { {:variable_rate => count_hourly_rate.to_s} }

let(:detail_params) do
{
:chargeback_rate_detail_fixed_compute_cost => {:tiers => [hourly_variable_tier_rate]},
:chargeback_rate_detail_metering_used => {:tiers => [hourly_variable_tier_rate]}
:chargeback_rate_detail_fixed_compute_cost => {:tiers => [hourly_variable_tier_rate]},
:chargeback_rate_detail_metering_used => {:tiers => [hourly_variable_tier_rate]},
:chargeback_rate_detail_cpu_cores_allocated => {:tiers => [count_hourly_variable_tier_rate]},
:chargeback_rate_detail_memory_allocated => {:tiers => [hourly_variable_tier_rate]}
}
end

Expand All @@ -40,7 +44,8 @@
@project = FactoryGirl.create(:container_project, :name => "my project", :ext_management_system => ems)
@group = FactoryGirl.create(:container_group, :ext_management_system => ems, :container_project => @project,
:container_node => @node)
@container = FactoryGirl.create(:kubernetes_container, :container_group => @group, :container_image => @image)
@container = FactoryGirl.create(:kubernetes_container, :container_group => @group, :container_image => @image,
:limit_memory_bytes => 1.megabytes, :limit_cpu_cores => 1.0)
cat = FactoryGirl.create(:classification, :description => "Environment", :name => "environment", :single_value => true, :show => true)
c = FactoryGirl.create(:classification, :name => "prod", :description => "Production", :parent_id => cat.id)
ChargebackRate.set_assignments(:compute, [{ :cb_rate => chargeback_rate, :tag => [c, "container_image"] }])
Expand Down Expand Up @@ -92,6 +97,14 @@
expect(subject.metering_used_metric).to eq(hours_in_day)
expect(subject.metering_used_cost).to eq(hours_in_day * hourly_rate)
end

it "allocated fields" do
skip('this feature needs to be added to new chargeback rating') if Settings.new_chargeback
expect(subject.cpu_cores_allocated_cost).to eq(@container.limit_cpu_cores * count_hourly_rate * hours_in_day)
expect(subject.cpu_cores_allocated_metric).to eq(@container.limit_cpu_cores)
expect(subject.cpu_cores_allocated_cost).to eq(@container.limit_memory_bytes / 1.megabytes * count_hourly_rate * hours_in_day)
expect(subject.cpu_cores_allocated_metric).to eq(@container.limit_memory_bytes / 1.megabytes)
end
end

context "Monthly" do
Expand All @@ -117,6 +130,14 @@
expect(subject.metering_used_metric).to eq(hours_in_month)
expect(subject.metering_used_cost).to eq(hours_in_month * hourly_rate)
end

it "allocated fields" do
skip('this feature needs to be added to new chargeback rating') if Settings.new_chargeback
expect(subject.cpu_cores_allocated_cost).to eq(@container.limit_cpu_cores * count_hourly_rate * hours_in_month)
expect(subject.cpu_cores_allocated_metric).to eq(@container.limit_cpu_cores)
expect(subject.cpu_cores_allocated_cost).to eq(@container.limit_memory_bytes / 1.megabytes * count_hourly_rate * hours_in_month)
expect(subject.cpu_cores_allocated_metric).to eq(@container.limit_memory_bytes / 1.megabytes)
end
end

context "Label" do
Expand Down
1 change: 1 addition & 0 deletions spec/models/chargeback_rate_detail_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
rates = ChargebackRateDetail.default_rate_details_for('Compute')
expected_metrics = %w(
derived_vm_numvcpus
derived_vm_numvcpu_cores
cpu_usagemhz_rate_average
v_derived_cpu_total_cores_used
disk_usage_rate_average
Expand Down

0 comments on commit 9767bea

Please sign in to comment.