Skip to content

Fix ae engine tags #555

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
13 changes: 11 additions & 2 deletions lib/miq_automation_engine/engine/miq_ae_engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def self.create_automation_attribute_array_key(key)

def self.create_automation_attribute_array_value(value)
value.collect do |obj|
obj.kind_of?(ActiveRecord::Base) ? obj.id.to_s : obj.to_s
obj.kind_of?(ActiveRecord::Base) ? "#{obj.class.name}::#{obj.id}" : obj.to_s
end
end

Expand Down Expand Up @@ -320,7 +320,13 @@ def self.create_ae_attrs(attrs, name, vmdb_object, objects = [MiqServer.my_serve
array_objects.each do |array_object|
# Each array attribute is tagged with Array:: before the attribute key unless it already starts with Array::
array_attr_key = array_object
if !array_object.starts_with?("Array::")
if !ae_attrs[array_object].empty? && ae_attrs[array_object].first.to_s.split("::").first == "Classification"
array_attr_key = if array_object.starts_with?("Array::")
"Tag#{array_object}"
else
"TagArray::#{array_object}"
end
elsif !array_object.starts_with?("Array::")
array_attr_key = "Array::#{array_object}"
end
ae_attrs[array_attr_key] = ae_attrs[array_object].collect do |obj|
Expand All @@ -329,6 +335,9 @@ def self.create_ae_attrs(attrs, name, vmdb_object, objects = [MiqServer.my_serve
if !array_object.starts_with?("Array::")
ae_attrs.delete(array_object)
end
if !array_object.starts_with?("TagArray::") && array_attr_key.starts_with?("TagArray::")
ae_attrs.delete(array_object)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what's being deleted here. It looks like it's removing non-array objects. If we need to do all of those conditions, you can combine them:

if !array_object.starts_with?("Array::") || (!array_object.starts_with?("TagArray::") && array_attr_key.starts_with?("TagArray::"))
  ae_attrs.delete(array_object)
end

end
ae_attrs
end
Expand Down
23 changes: 19 additions & 4 deletions lib/miq_automation_engine/engine/miq_ae_engine/miq_ae_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -258,19 +258,34 @@ def process_args_as_attributes(args = {})
end

def process_args_array(args, args_key)
# process Array::servers => MiqServer::2,MiqServer::3,MiqServer::4
# Process Array::servers => MiqServer::2,MiqServer::3,MiqServer::4
# If no class seperator exists then return Array::servers => 2,3,4
key = args_key.split(CLASS_SEPARATOR).last
value = args.delete(args_key)
args[key.downcase] = load_array_objects_from_string(value)
end

def attribute_is_array?(attr)
attr.to_s.downcase.starts_with?("array::")
attr.to_s.downcase.starts_with?("array::") && !attr.to_s.downcase.starts_with?("tagarray")
end

def process_args_attribute(args, args_key)
# process MiqServer::svr => 2
if args_key.include?(CLASS_SEPARATOR)
# Process TagArray::dialog_tags => <Classification ...>, <Classification ...>, <Classification ...>
if args_key.to_s.downcase.starts_with?("tagarray")
tags = []
args[args_key].split("\u001F").each do |tag|
# args_key: TagArray::dialog_param_test1
# args[args_key]: <Classification ...>, <Classification ...>, <Classification ...>
# tag: <Classification ...>
key, klass = get_key_name_and_klass_from_key(tag)
tags.push(MiqAeObject.convert_value_based_on_datatype(key, klass))
args["#{key}_id"] = tag if attribute_for_vmdb_object?(klass, args[args_key]) && [email protected]?(key)
end
args.delete(args_key)
key = args_key.split("::").last
args[key] = tags
# Process MiqServer::svr => 2
elsif args_key.include?(CLASS_SEPARATOR)
key, klass = get_key_name_and_klass_from_key(args_key)
value = args.delete(args_key)
args["#{key}_id"] = value if attribute_for_vmdb_object?(klass, value) && [email protected]?(key)
Expand Down
72 changes: 54 additions & 18 deletions spec/miq_ae_engine_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,8 @@ def call_automate(obj_type, obj_id, open_url_task_id = nil)

it "will process an array of objects with a server and user" do
extras = "MiqServer%3A%3Amiq_server=12"
FactoryBot.create(:small_environment)
attrs = {"MiqServer::miq_server" => "12", "array::tag" => "Classification::1,Classification::2"}
result_str = "array%3A%3Atag=Classification%3A%3A1%2CClassification%3A%3A2"
attrs = {"MiqServer::miq_server" => "12", "Array::tags" => ["Classification::1,Classification::2"]}
result_str = "TagArray%3A%3Atags=Classification%3A%3A1%2CClassification%3A%3A2"
uri = "/System/Process/AUTOMATION?#{extras}&#{result_str}&object_name=AUTOMATION"
expect(MiqAeEngine.create_automation_object("AUTOMATION", attrs)).to eq(uri)
end
Expand Down Expand Up @@ -375,20 +374,22 @@ def call_automate(obj_type, obj_id, open_url_task_id = nil)
end

it "with an array of Vms" do
result_arr = []
hash = {"vms" => Vm.all}
result_str = "vms=#{hash["vms"].collect { |v| v.id.to_s }.join("=")}"
hash["vms"].collect { |v| result_arr.push(v.id.to_s) }
result_str = "vms=#{hash["vms"].collect { |v| "ManageIQ::Providers::Vmware::InfraManager::Vm::#{v.id}" }.join("=")}"
result = MiqAeEngine.create_automation_attributes(hash)
result_arr = if hash["vms"].length == 1
"ManageIQ::Providers::Vmware::InfraManager::Vm::#{hash["vms"][0].id}"
else
hash["vms"].collect { |v| "ManageIQ::Providers::Vmware::InfraManager::Vm::#{v.id}" }
end
expect(MiqAeEngine.create_automation_attributes_string(hash)).to eq(result_str)
expect(result["vms"]).to eq(result_arr)
end

it "with an array containing a single Vm" do
result_arr = []
hash = {"vms" => [Vm.first]}
result_str = "vms=#{hash["vms"].collect { |v| v.id.to_s }.join("=")}"
hash["vms"].collect { |v| result_arr.push(v.id.to_s) }
result_str = "vms=#{hash["vms"].collect { |v| "ManageIQ::Providers::Vmware::InfraManager::Vm::#{v.id}" }.join("=")}"
result_arr = ["ManageIQ::Providers::Vmware::InfraManager::Vm::#{hash["vms"][0].id}"]
result = MiqAeEngine.create_automation_attributes(hash)
expect(MiqAeEngine.create_automation_attributes_string(hash)).to eq(result_str)
expect(result["vms"]).to eq(result_arr)
Expand All @@ -408,24 +409,21 @@ def call_automate(obj_type, obj_id, open_url_task_id = nil)
end

it "with an array of Hosts" do
result_arr = []
hash = {"hosts" => Host.all}
result_str = "hosts=#{hash["hosts"].collect { |h| h.id.to_s }.join("=")}"
hash["hosts"].collect { |h| result_arr.push(h.id.to_s) }
result_str = "hosts=#{hash["hosts"].collect { |h| "Host::#{h.id}" }.join("=")}"
result_arr = hash["hosts"].collect { |h| "Host::#{h.id}" }
result = MiqAeEngine.create_automation_attributes(hash)
expect(MiqAeEngine.create_automation_attributes_string(hash)).to eq(result_str)
expect(result["hosts"]).to eq(result_arr)
end

it "with multiple arrays" do
vm_result_arr = []
host_result_arr = []
hash = {"vms" => Vm.all}
vm_result_str = "vms=#{hash["vms"].collect { |v| v.id.to_s }.join("=")}"
hash["vms"].collect { |v| vm_result_arr.push(v.id.to_s) }
vm_result_str = "vms=#{hash["vms"].collect { |v| "ManageIQ::Providers::Vmware::InfraManager::Vm::#{v.id}" }.join("=")}"
vm_result_arr = hash["vms"].collect { |v| "ManageIQ::Providers::Vmware::InfraManager::Vm::#{v.id}" }
hash["hosts"] = Host.all
host_result_str = "hosts=#{hash["hosts"].collect { |h| h.id.to_s }.join("=")}"
hash["hosts"].collect { |h| host_result_arr.push(h.id.to_s) }
host_result_str = "hosts=#{hash["hosts"].collect { |h| "Host::#{h.id}" }.join("=")}"
host_result_arr = hash["hosts"].collect { |h| "Host::#{h.id}" }
result = MiqAeEngine.create_automation_attributes(hash)
expect(result["vms"]).to eq(vm_result_arr)
expect(result["hosts"]).to eq(host_result_arr)
Expand All @@ -434,6 +432,22 @@ def call_automate(obj_type, obj_id, open_url_task_id = nil)
expect(result_str).to include(host_result_str)
end

it "with an array of Tags" do
FactoryBot.create(:classification)
FactoryBot.create(:classification)
FactoryBot.create(:classification)
hash = {"tags" => Classification.all}
result_str = "tags=#{hash["tags"].collect { |h| "Classification::#{h.id}" }.join("=")}"
result_arr = if hash["tags"].length == 1
"Classification::#{hash["tags"][0].id}"
else
hash["tags"].collect { |h| "Classification::#{h.id}" }
end
result = MiqAeEngine.create_automation_attributes(hash)
expect(MiqAeEngine.create_automation_attributes_string(hash)).to eq(result_str)
expect(result["tags"]).to eq(result_arr)
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GilbertCherrie Did we completely revert the test changes so it's testing as it was before? This test looks new but others are changes. Basically, it's hard to determine the changes we're doing on code pre #545. I can't tell if you did a full revert of the prior changes in the repos and then made changes on top or we're keeping some of the changes from #545 and just fixing it to work with the original tests.

it "with invalid object references" do
hash = {"vms" => ["bogus::12"]}
result = MiqAeEngine.create_automation_attributes(hash)
Expand Down Expand Up @@ -789,6 +803,28 @@ def call_automate(obj_type, obj_id, open_url_task_id = nil)
my_objects_array.each { |o| o.kind_of?(MiqAeMethodService::MiqAeServiceModelBase) }
end

it "processes tags array arguments properly" do
tag1 = FactoryBot.create(:classification)
tag2 = FactoryBot.create(:classification)
tag3 = FactoryBot.create(:classification)

EvmSpecHelper.import_yaml_model(File.join(model_data_dir, "miq_ae_engine_spec5"), domain)
ws = MiqAeEngine.instantiate("/EVM/AUTOMATE/test1?TagArray::my_objects=Classification::#{tag1.id}\x1FClassification::#{tag2.id}\x1FClassification::#{tag3.id}", user)
my_objects_array = ws.root("my_objects")
expect(my_objects_array.length).to eq(3)
my_objects_array.each { |o| o.kind_of?(MiqAeMethodService::MiqAeServiceModelBase) }
end

it "processes tags array with a single value arguments properly" do
tag1 = FactoryBot.create(:classification)

EvmSpecHelper.import_yaml_model(File.join(model_data_dir, "miq_ae_engine_spec5"), domain)
ws = MiqAeEngine.instantiate("/EVM/AUTOMATE/test1?TagArray::my_objects=Classification::#{tag1.id}", user)
my_objects_array = ws.root("my_objects")
expect(my_objects_array.length).to eq(1)
my_objects_array.each { |o| o.kind_of?(MiqAeMethodService::MiqAeServiceModelBase) }
end

it "processes an empty array properly" do
EvmSpecHelper.import_yaml_model(File.join(model_data_dir, "miq_ae_engine_spec6"), domain)
ws = MiqAeEngine.instantiate("/EVM/AUTOMATE/test1?Array::my_objects=", user)
Expand Down