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

Change the target of tag expressions #15715

Merged
merged 2 commits into from
Aug 4, 2017
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
25 changes: 25 additions & 0 deletions lib/miq_expression.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ def valid?(component = exp)
end
end

def set_tagged_target(model, associations = [])
each_atom(exp) do |atom|
next unless atom.key?("tag")
tag = Tag.parse(atom["tag"])
tag.model = model
tag.associations = associations
atom["tag"] = tag.to_s
end
end

def self.proto?
return @proto if defined?(@proto)
@proto = ::Settings.product.proto
Expand Down Expand Up @@ -1436,4 +1446,19 @@ def self.determine_relat_path(ref)
last_path
end
private_class_method :determine_relat_path

def each_atom(component, &block)
operator = component.keys.first

case operator.downcase
when "and", "or"
component[operator].each { |sub_component| each_atom(sub_component, &block) }
when "not", "!"
each_atom(component[operator], &block)
when "find"
component[operator].each { |_operator, operands| each_atom(operands, &block) }
else
yield(component[operator])
end
end
end # class MiqExpression
1 change: 1 addition & 0 deletions lib/miq_expression/field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class MiqExpression::Field < MiqExpression::Target

def self.parse(field)
parsed_params = parse_params(field) || return
return unless parsed_params[:model_name]
new(parsed_params[:model_name], parsed_params[:associations], parsed_params[:column] ||
parsed_params[:virtual_custom_column])
end
Expand Down
4 changes: 2 additions & 2 deletions lib/miq_expression/tag.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class MiqExpression::Tag < MiqExpression::Target
REGEX = /
(?<model_name>([[:alnum:]]*(::)?)+)
\.(?<associations>([a-z_]+\.)*)
(?<model_name>([[:alnum:]]*(::)?)?)
\.?(?<associations>([a-z_]+\.)*)
(?<namespace>\bmanaged|user_tag\b)
-(?<column>[a-z]+[_[:alnum:]]+)
/x
Expand Down
5 changes: 3 additions & 2 deletions lib/miq_expression/target.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ def self.parse_params(field)
# convert matches to hash to format
# {:model_name => 'User', :associations => ...}
parsed_params = Hash[match.names.map(&:to_sym).zip(match.to_a[1..-1])]
parsed_params[:model_name] = parsed_params[:model_name].classify.safe_constantize || return
parsed_params[:model_name] = parsed_params[:model_name].classify.safe_constantize
parsed_params[:associations] = parsed_params[:associations].to_s.split(".")
parsed_params
end

attr_reader :model, :associations, :column
attr_reader :column
attr_accessor :model, :associations

def initialize(model, associations, column)
@model = model
Expand Down
6 changes: 4 additions & 2 deletions spec/lib/miq_expression/tag_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@
expect(described_class.parse(tag)).to be_nil
end

it "returns nil with invalid case managed-tag" do
it "supports managed-tag (no model)" do
tag = "managed-service_level"
expect(described_class.parse(tag)).to be_nil
expect(described_class.parse(tag)).to have_attributes(:model => nil,
:associations => [],
:namespace => "/managed/service_level")
end

it "returns nil with invalid case managed" do
Expand Down
81 changes: 81 additions & 0 deletions spec/lib/miq_expression_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3152,4 +3152,85 @@
)
end
end

describe "#set_tagged_target" do
it "will substitute a new class into the expression" do
expression = described_class.new("CONTAINS" => {"tag" => "managed-environment", "value" => "prod"})

expression.set_tagged_target(Vm)

expect(expression.exp).to eq("CONTAINS" => {"tag" => "Vm.managed-environment", "value" => "prod"})
end

it "will substitute a new class and associations into the expression" do
expression = described_class.new("CONTAINS" => {"tag" => "managed-environment", "value" => "prod"})

expression.set_tagged_target(Vm, ["host"])

expect(expression.exp).to eq("CONTAINS" => {"tag" => "Vm.host.managed-environment", "value" => "prod"})
end

it "can handle OR expressions" do
expression = described_class.new(
"OR" => [
{"CONTAINS" => {"tag" => "managed-environment", "value" => "prod"}},
{"CONTAINS" => {"tag" => "managed-location", "value" => "ny"}}
]
)

expression.set_tagged_target(Vm)

expected = {
"OR" => [
{"CONTAINS" => {"tag" => "Vm.managed-environment", "value" => "prod"}},
{"CONTAINS" => {"tag" => "Vm.managed-location", "value" => "ny"}}
]
}
expect(expression.exp).to eq(expected)
end

it "can handle AND expressions" do
expression = described_class.new(
"AND" => [
{"CONTAINS" => {"tag" => "managed-environment", "value" => "prod"}},
{"CONTAINS" => {"tag" => "managed-location", "value" => "ny"}}
]
)

expression.set_tagged_target(Vm)

expected = {
"AND" => [
{"CONTAINS" => {"tag" => "Vm.managed-environment", "value" => "prod"}},
{"CONTAINS" => {"tag" => "Vm.managed-location", "value" => "ny"}}
]
}
expect(expression.exp).to eq(expected)
end

it "can handle NOT expressions" do
expression = described_class.new("NOT" => {"CONTAINS" => {"tag" => "managed-environment", "value" => "prod"}})

expression.set_tagged_target(Vm)

expected = {"NOT" => {"CONTAINS" => {"tag" => "Vm.managed-environment", "value" => "prod"}}}
expect(expression.exp).to eq(expected)
end

it "will not change the target of fields" do
expression = described_class.new("=" => {"field" => "Vm-vendor", "value" => "redhat"})

expression.set_tagged_target(Host)

expect(expression.exp).to eq("=" => {"field" => "Vm-vendor", "value" => "redhat"})
end

it "will not change the target of counts" do
expression = described_class.new("=" => {"count" => "Vm.disks", "value" => "1"})

expression.set_tagged_target(Host)

expect(expression.exp).to eq("=" => {"count" => "Vm.disks", "value" => "1"})
end
end
end