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

Generate virtual custom attributes with sections #14837

15 changes: 12 additions & 3 deletions app/models/mixins/custom_attribute_mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ module CustomAttributeMixin
end

def self.custom_keys
CustomAttribute.where(:resource_type => base_class).distinct.pluck(:name).compact
custom_attr_scope = CustomAttribute.where(:resource_type => base_class).where.not(:name => nil).distinct.pluck(:name, :section)
custom_attr_scope.map do |x|
"#{x[0]}#{x[1] ? SECTION_SEPARATOR + x[1] : ''}"
end
end

def self.load_custom_attributes_for(cols)
Expand All @@ -41,8 +44,14 @@ def self.add_custom_attribute(custom_attribute)
virtual_column(custom_attribute.to_sym, :type => :string, :uses => :custom_attributes)

define_method(custom_attribute.to_sym) do
custom_attribute_without_prefix = custom_attribute.sub(CUSTOM_ATTRIBUTES_PREFIX, "")
custom_attributes.detect { |x| custom_attribute_without_prefix == x.name }.try(:value)
custom_attribute_without_prefix = custom_attribute.sub(CUSTOM_ATTRIBUTES_PREFIX, "")
custom_attribute_without_section, section = custom_attribute_without_prefix.split(SECTION_SEPARATOR)

where_args = {}
where_args[:name] = custom_attribute_without_section
where_args[:section] = section if section

custom_attributes.find_by(where_args).try(:value)
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/miq_expression/field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class MiqExpression::Field < MiqExpression::Target
\.?(?<associations>[a-z][0-9a-z_\.]+)?
-
(?:
(?<virtual_custom_column>#{CustomAttributeMixin::CUSTOM_ATTRIBUTES_PREFIX}[a-z]+[_\-.\/[:alnum:]]*)|
(?<virtual_custom_column>#{CustomAttributeMixin::CUSTOM_ATTRIBUTES_PREFIX}[a-z]+[:_\-.\/[:alnum:]]*)|
(?<column>[a-z]+(_[[:alnum:]]+)*)
)
/x
Expand Down
21 changes: 21 additions & 0 deletions spec/lib/miq_expression_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1919,6 +1919,27 @@
it "ignores custom_attibutes with a nil name" do
expect(MiqExpression._custom_details_for("Vm", {})).to eq([["Custom Attribute: CATTR_1", "Vm-virtual_custom_attribute_CATTR_1"]])
end

let(:conatiner_image) { FactoryGirl.create(:container_image) }

let!(:custom_attribute_with_section_1) do
FactoryGirl.create(:custom_attribute, :resource => conatiner_image, :name => 'CATTR_3', :value => "Value 3",
:section => 'section_3')
end

let!(:custom_attribute_with_section_2) do
FactoryGirl.create(:custom_attribute, :resource => conatiner_image, :name => 'CATTR_3', :value => "Value 3",
:section => 'docker_labels')
end

it "returns human names of custom attributes with sections" do
expected_result = [
['Docker Labels: CATTR_3', 'ContainerImage-virtual_custom_attribute_CATTR_3:SECTION:docker_labels'],
['Section 3: CATTR_3', 'ContainerImage-virtual_custom_attribute_CATTR_3:SECTION:section_3']
]

expect(MiqExpression._custom_details_for("ContainerImage", {})).to match_array(expected_result)
end
end

context ".build_relats" do
Expand Down
49 changes: 49 additions & 0 deletions spec/models/miq_report_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,55 @@
)
end

context 'with container images' do
let(:report) do
MiqReport.new(
:name => "Custom VM report", :title => "Custom VM report", :rpt_group => "Custom", :rpt_type => "Custom",
:db => "ContainerImage",
:cols => ['name',
"virtual_custom_attribute_CATTR#{CustomAttributeMixin::SECTION_SEPARATOR}docker_labels",
"virtual_custom_attribute_CATTR#{CustomAttributeMixin::SECTION_SEPARATOR}labels"],
:include => {:custom_attributes => {}},
:col_order => %w(name CATTR),
:headers => ["Name", custom_column_key_1, custom_column_key_1],
:order => "Ascending"
)
end

let!(:container_image) do
FactoryGirl.create(:container_image, :name => "test_container_images")
end

let!(:custom_attribute_1) do
FactoryGirl.create(:custom_attribute, :resource => container_image, :name => 'CATTR', :value => 'any_value',
:section => 'docker_labels')
end

let!(:custom_attribute_2) do
FactoryGirl.create(:custom_attribute, :resource => container_image, :name => 'CATTR', :value => 'other_value',
:section => 'labels')
end

it "generates report with dynamic custom attributes" do
report.queue_generate_table(:userid => user.userid)
report._async_generate_table(miq_task.id, :userid => user.userid, :mode => "async",
:report_source => "Requested by user")

report_result = report.table.data.map do |x|
x.data.delete("id")
x.data
end

expected_results = [
{"name" => "test_container_images",
"virtual_custom_attribute_CATTR#{CustomAttributeMixin::SECTION_SEPARATOR}docker_labels" => "any_value",
"virtual_custom_attribute_CATTR#{CustomAttributeMixin::SECTION_SEPARATOR}labels" => "other_value"}
]

expect(report_result).to match_array(expected_results)
end
end

it "generates report with dynamic custom attributes" do
report.queue_generate_table(:userid => user.userid)
report._async_generate_table(miq_task.id, :userid => user.userid, :mode => "async",
Expand Down
15 changes: 15 additions & 0 deletions spec/models/mixins/custom_attribute_mixin_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,21 @@ def self.name; "TestClass"; end
end
end

describe '#custom_keys' do
let!(:custom_attribute) { FactoryGirl.create(:custom_attribute, :name => "attr_1", :value => 'value') }
let!(:custom_attribute_with_section) do
FactoryGirl.create(:custom_attribute, :name => "attr_2", :value => 'value', :section => 'labels')
end

let!(:vm) do
FactoryGirl.create(:vm_redhat, :custom_attributes => [custom_attribute, custom_attribute_with_section])
end

it 'returns human form of virtual custom attribute with sections' do
expect(vm.class.custom_keys).to match_array(["attr_1", "attr_2#{described_class::SECTION_SEPARATOR}labels"])
end
end

it "defines #miq_custom_keys" do
expect(test_class.new).to respond_to(:miq_custom_keys)
end
Expand Down