Skip to content

Commit

Permalink
Merge pull request #10897 from alongoldboim/provider_meta_data
Browse files Browse the repository at this point in the history
Adding custom attributes to provider (UI + API)
(cherry picked from commit 46277ee)
  • Loading branch information
gtanzillo authored and chessbyte committed Oct 13, 2016
1 parent 80309ec commit a16aedc
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 0 deletions.
21 changes: 21 additions & 0 deletions app/controllers/api/providers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class ProvidersController < BaseController
include Subcollections::PolicyProfiles
include Subcollections::Tags
include Subcollections::CloudNetworks
include Subcollections::CustomAttributes

def create_resource(type, _id, data = {})
assert_id_not_specified(data, type)
Expand Down Expand Up @@ -50,8 +51,28 @@ def delete_resource(type, id = nil, _data = nil)
end
end

def custom_attributes_edit_resource(object, type, id, data = nil)
formatted_data = format_provider_custom_attributes(data)
super(object, type, id, formatted_data)
end

def custom_attributes_add_resource(object, type, id, data = nil)
formatted_data = format_provider_custom_attributes(data)
super(object, type, id, formatted_data)
end

private

def format_provider_custom_attributes(attribute)
if CustomAttribute::ALLOWED_API_VALUE_TYPES.include? attribute["field_type"]
attribute["value"] = attribute.delete("field_type").safe_constantize.parse(attribute["value"])
end
attribute["section"] = "metadata" unless @req.action == "edit"
attribute
rescue => err
raise BadRequestError, "Invalid provider custom attributes specified - #{err}"
end

def provider_ident(provider)
"Provider id:#{provider.id} name:'#{provider.name}'"
end
Expand Down
6 changes: 6 additions & 0 deletions app/helpers/ems_container_helper/textual_summary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,10 @@ def textual_endpoints
{:label => _('Hawkular API Port'),
:value => @ems.connection_configurations.hawkular.endpoint.port}]
end

def textual_miq_custom_attributes
attrs = @record.custom_attributes
return nil if attrs.blank?
attrs.collect { |a| {:label => a.name.tr("_", " "), :value => a.value} }
end
end
1 change: 1 addition & 0 deletions app/models/custom_attribute.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class CustomAttribute < ApplicationRecord
ALLOWED_API_VALUE_TYPES = %w(DateTime Time Date).freeze
belongs_to :resource, :polymorphic => true
serialize :serialized_value

Expand Down
2 changes: 2 additions & 0 deletions app/views/ems_container/_main.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
-# commented out to hide Component Statuses table since the information is currently broken (see Issue #8572)
-# = render :partial => "shared/summary/textual_multilabel", :locals => {:title => _("Component Statuses"),
-# :items => textual_group_component_statuses}
= render :partial => "shared/summary/textual", :locals => {:title => _("Custom Attributes"),
:items => textual_miq_custom_attributes}
.col-sm-12.col-md-12.col-lg-6
= render :partial => "shared/summary/textual", :locals => {:title => _("Relationships"),
:items => textual_group_relationships}
Expand Down
9 changes: 9 additions & 0 deletions config/api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,7 @@
- :policies
- :policy_profiles
- :cloud_networks
- :custom_attributes
:collection_actions:
:get:
- :name: read
Expand Down Expand Up @@ -781,6 +782,14 @@
:identifier: ems_infra_tag
- :name: unassign
:identifier: ems_infra_tag
:custom_attributes_subcollection_actions:
:post:
- :name: add
:identifier: ems_infra_edit
- :name: edit
:identifier: ems_infra_edit
- :name: delete
:identifier: ems_infra_edit
:policies_subcollection_actions:
:post:
- :name: assign
Expand Down
24 changes: 24 additions & 0 deletions spec/helpers/ems_cotainer_helper/textual_summary_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
describe EmsContainerHelper::TextualSummary do
context "providers custom attributes" do
before do
@record = FactoryGirl.build(:ems_openshift)
allow_any_instance_of(described_class).to receive(:role_allows?).and_return(true)
allow(controller).to receive(:restful?).and_return(true)
allow(controller).to receive(:controller_name).and_return("ems_container")
end

it "should parse custom attributes to labels and values" do
@record.custom_attributes << FactoryGirl.build(:custom_attribute,
:name => "Example_custom_attribute",
:value => 4)

expect(textual_miq_custom_attributes.first[:label]).to eq("Example custom attribute")

expect(textual_miq_custom_attributes.first[:value]).to eq("4")
end

it "should return nil if no custom attributes" do
expect(textual_miq_custom_attributes).to eq(nil)
end
end
end
126 changes: 126 additions & 0 deletions spec/requests/api/providers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,132 @@
}
end

context "Provider custom_attributes" do
let(:provider) { FactoryGirl.create(:ext_management_system, sample_rhevm) }
let(:provider_url) { providers_url(provider.id) }
let(:ca1) { FactoryGirl.create(:custom_attribute, :name => "name1", :value => "value1") }
let(:ca2) { FactoryGirl.create(:custom_attribute, :name => "name2", :value => "value2") }
let(:provider_ca_url) { "#{provider_url}/custom_attributes" }
let(:ca1_url) { "#{provider_ca_url}/#{ca1.id}" }
let(:ca2_url) { "#{provider_ca_url}/#{ca2.id}" }
let(:provider_ca_url_list) { [ca1_url, ca2_url] }

it "getting custom_attributes from a provider with no custom_attributes" do
api_basic_authorize

run_get(provider_ca_url)

expect_empty_query_result(:custom_attributes)
end

it "getting custom_attributes from a provider" do
api_basic_authorize
provider.custom_attributes = [ca1, ca2]

run_get provider_ca_url

expect_query_result(:custom_attributes, 2)

expect_result_resources_to_include_hrefs("resources", :provider_ca_url_list)
end

it "getting custom_attributes from a provider in expanded form" do
api_basic_authorize
provider.custom_attributes = [ca1, ca2]

run_get provider_ca_url, :expand => "resources"

expect_query_result(:custom_attributes, 2)

expect_result_resources_to_include_data("resources", "name" => %w(name1 name2))
end

it "getting custom_attributes from a provider using expand" do
api_basic_authorize action_identifier(:providers, :read, :resource_actions, :get)
provider.custom_attributes = [ca1, ca2]

run_get provider_url, :expand => "custom_attributes"

expect_single_resource_query("guid" => provider.guid)

expect_result_resources_to_include_data("custom_attributes", "name" => %w(name1 name2))
end

it "delete a custom_attribute without appropriate role" do
api_basic_authorize
provider.custom_attributes = [ca1]

run_post(provider_ca_url, gen_request(:delete, nil, provider_url))

expect(response).to have_http_status(:forbidden)
end

it "delete a custom_attribute from a provider via the delete action" do
api_basic_authorize action_identifier(:providers, :edit)
provider.custom_attributes = [ca1]

run_post(provider_ca_url, gen_request(:delete, nil, ca1_url))

expect(response).to have_http_status(:ok)

expect(provider.reload.custom_attributes).to be_empty
end

it "add custom attribute to a provider without a name" do
api_basic_authorize action_identifier(:providers, :edit)

run_post(provider_ca_url, gen_request(:add, "value" => "value1"))

expect_bad_request("Must specify a name")
end

it "add custom attributes to a provider" do
api_basic_authorize action_identifier(:providers, :edit)

run_post(provider_ca_url, gen_request(:add, [{"name" => "name1", "value" => "value1"},
{"name" => "name2", "value" => "value2"}]))
expected = {
"results" => a_collection_containing_exactly(
a_hash_including("name" => "name1", "value" => "value1", "section" => "metadata"),
a_hash_including("name" => "name2", "value" => "value2", "section" => "metadata")
)
}
expect(response).to have_http_status(:ok)

expect(response.parsed_body).to include(expected)

expect(provider.custom_attributes.size).to eq(2)
end

it "formats custom attribute of type date" do
api_basic_authorize action_identifier(:providers, :edit)
date_field = DateTime.new.in_time_zone

run_post(provider_ca_url, gen_request(:add, [{"name" => "name1",
"value" => date_field,
"field_type" => "DateTime"}]))

expect(response).to have_http_status(:ok)

expect(provider.custom_attributes.first.serialized_value).to eq(date_field)

expect(provider.custom_attributes.first.section).to eq("metadata")
end

it "edit a custom attribute by name" do
api_basic_authorize action_identifier(:providers, :edit)
provider.custom_attributes = [ca1]

run_post(provider_ca_url, gen_request(:edit, "name" => "name1", "value" => "value one"))

expect(response).to have_http_status(:ok)

expect_result_resources_to_include_data("results", "value" => ["value one"])

expect(provider.reload.custom_attributes.first.value).to eq("value one")
end
end

describe "Providers actions on Provider class" do
let(:foreman_type) { ManageIQ::Providers::Foreman::Provider }
let(:sample_foreman) do
Expand Down

0 comments on commit a16aedc

Please sign in to comment.