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

Pass metadata from an EmsEvent to an alert #14136

Merged
merged 2 commits into from
Mar 8, 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
8 changes: 8 additions & 0 deletions app/models/ems_event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,14 @@ def self.first_chained_event(ems_id, chain_id)
EmsEvent.where(:ems_id => ems_id, :chain_id => chain_id).order(:id).first
end

def parse_event_metadata
[
event_type == "datawarehouse_alert" ? message : nil,
full_data.try(:[], :severity),
full_data.try(:[], :url),
]
end

def first_chained_event
@first_chained_event ||= EmsEvent.first_chained_event(ems_id, chain_id) || self
end
Expand Down
8 changes: 5 additions & 3 deletions app/models/miq_alert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -193,16 +193,18 @@ def evaluate(target, inputs = {})
# If we are alerting, invoke the alert actions, then add a status so we can limit how often to alert
# Otherwise, destroy this alert's statuses for our target
invoke_actions(target, inputs) if result
add_status_post_evaluate(target, result, inputs[:description])

add_status_post_evaluate(target, result, inputs[:ems_event])
Copy link
Author

Choose a reason for hiding this comment

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

the inputs[:description] is a bug I recently introduced in #13653

Copy link

Choose a reason for hiding this comment

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

Can you extract this change into a different commit so info is retained on the change?

result
end

def add_status_post_evaluate(target, result, status_description)
def add_status_post_evaluate(target, result, event)
status_description, severity, url = event.parse_event_metadata if event.respond_to?(:parse_event_metadata)
status = miq_alert_statuses.find_or_initialize_by(:resource => target)
status.result = result
status.ems_id = target.try(:ems_id)
status.description = status_description || description
Copy link
Author

Choose a reason for hiding this comment

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

Is it worth to change the above to

status_description.blank? description : status_description

Prefer to do it in another pr though.

status.severity = severity unless severity.blank?
status.url = url unless url.blank?
status.evaluated_on = Time.now.utc
status.save
miq_alert_statuses << status
Expand Down
59 changes: 57 additions & 2 deletions spec/models/miq_alert_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,32 +96,86 @@
before(:each) do
@alert = MiqAlert.find_by(:description => "VM Unregistered")
allow(@alert).to receive_messages(:eval_expression => true)
@alert.evaluate([@vm.class.base_class.name, @vm.id])
end

it "should have a link from the MiqAlert to the miq alert status" do
@alert.evaluate([@vm.class.base_class.name, @vm.id])
expect(@alert.miq_alert_statuses.where(:resource_type => @vm.class.base_class.name, :resource_id => @vm.id).count).to eq(1)
end

it "should have a miq alert status for MiqAlert with a result of true" do
@alert.evaluate([@vm.class.base_class.name, @vm.id])
expect(@alert.miq_alert_statuses.find_by(:resource_type => @vm.class.base_class.name, :resource_id => @vm.id).result).to be_truthy
end

it "cookie stamps the description on the alert" do
it "does not explode if evaluate.input = {}" do
expect { @alert.evaluate([@vm.class.base_class.name, @vm.id]) }.to_not raise_error
end

it "miq_alert_status.description = miq_alert.description event if overriden by ems_event.description" do
@alert.evaluate(
[@vm.class.base_class.name, @vm.id],
:ems_event => FactoryGirl.create(:ems_event, :message => "oh no!", :type => 'WhateverEvent')
)
mas = @alert.miq_alert_statuses.where(:resource_type => @vm.class.base_class.name, :resource_id => @vm.id).first
expect(mas.description).to eq("VM Unregistered")
end

it "miq_alert_status.description = ems_event.message if present and datawarehouse_alert" do
@alert.evaluate(
[@vm.class.base_class.name, @vm.id],
:ems_event => FactoryGirl.create(:ems_event, :message => "oh no!", :event_type => "datawarehouse_alert")
)
mas = @alert.miq_alert_statuses.where(:resource_type => @vm.class.base_class.name, :resource_id => @vm.id).first
expect(mas.description).to eq("oh no!")
end

it "miq_alert_status.severity = ems_event.full_data.severity if present" do
@alert.evaluate(
[@vm.class.base_class.name, @vm.id],
:ems_event => FactoryGirl.create(:ems_event, :full_data => {:severity => 'warning'})
)
mas = @alert.miq_alert_statuses.where(:resource_type => @vm.class.base_class.name, :resource_id => @vm.id).first
expect(mas.severity).to eq('warning')
end

it "miq_alert_status.severity = nil if ems_event.full_data.severity not present" do
@alert.evaluate([@vm.class.base_class.name, @vm.id])
mas = @alert.miq_alert_statuses.where(:resource_type => @vm.class.base_class.name, :resource_id => @vm.id).first
expect(mas.severity).to eq(nil)
end

it "miq_alert_status.url = ems_event.full_data.url if present" do
@alert.evaluate(
[@vm.class.base_class.name, @vm.id],
:ems_event => FactoryGirl.create(
:ems_event,
:full_data => {:url => 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'}
)
)
mas = @alert.miq_alert_statuses.where(:resource_type => @vm.class.base_class.name, :resource_id => @vm.id).first
expect(mas.url).to eq('https://www.youtube.com/watch?v=dQw4w9WgXcQ')
end

it "miq_alert_status.url = nil if ems_event.full_data.url is not present" do
@alert.evaluate([@vm.class.base_class.name, @vm.id])
mas = @alert.miq_alert_statuses.where(:resource_type => @vm.class.base_class.name, :resource_id => @vm.id).first
expect(mas.url).to eq(nil)
end

it "should have a link from the Vm to the miq alert status" do
@alert.evaluate([@vm.class.base_class.name, @vm.id])
expect(@vm.miq_alert_statuses.where(:miq_alert_id => @alert.id).count).to eq(1)
end

it "should have a miq alert status for Vm with a result of true" do
@alert.evaluate([@vm.class.base_class.name, @vm.id])
expect(@vm.miq_alert_statuses.find_by(:miq_alert_id => @alert.id).result).to be_truthy
end

context "with the alert now evaluated to false" do
before(:each) do
@alert.evaluate([@vm.class.base_class.name, @vm.id])
allow(@alert).to receive_messages(:eval_expression => false)
@alert.options.store_path(:notifications, :delay_next_evaluation, 0)
@alert.evaluate([@vm.class.base_class.name, @vm.id])
Expand All @@ -146,6 +200,7 @@

context "with a delay_next_evaluation value of 5 minutes" do
before(:each) do
@alert.evaluate([@vm.class.base_class.name, @vm.id])
@alert.options ||= {}
@alert.options.store_path(:notifications, :delay_next_evaluation, 5.minutes)
@alert.save
Expand Down