diff --git a/app/controllers/api/alert_definitions_controller.rb b/app/controllers/api/alert_definitions_controller.rb index 4bac958aac..2b05a23d17 100644 --- a/app/controllers/api/alert_definitions_controller.rb +++ b/app/controllers/api/alert_definitions_controller.rb @@ -1,16 +1,13 @@ module Api class AlertDefinitionsController < BaseController - REQUIRED_FIELDS = %w(description db expression options).freeze - before_action :set_additional_attributes def create_resource(type, id, data = {}) assert_id_not_specified(data, type) - assert_all_required_fields_exists(data, type, REQUIRED_FIELDS) begin - data["expression"] = MiqExpression.new(data["expression"]) - data["enabled"] = true if data["enabled"].nil? - super(type, id, data).serializable_hash.merge("expression" => data["expression"]) + set_miq_expression(data) if data["expression"] + alert = super(type, id, data.deep_symbolize_keys).serializable_hash + alert.merge("expression" => alert["miq_expression"] || alert["hash_expression"]) rescue => err raise BadRequestError, "Failed to create a new alert definition - #{err}" end @@ -19,8 +16,8 @@ def create_resource(type, id, data = {}) def edit_resource(type, id = nil, data = {}) raise BadRequestError, "Must specify an id for editing a #{type} resource" unless id begin - data["expression"] = MiqExpression.new(data["expression"]) if data["expression"] - super(type, id, data) + set_miq_expression(data) if data["expression"] + super(type, id, data.deep_symbolize_keys) rescue => err raise BadRequestError, "Failed to update alert definition - #{err}" end @@ -31,5 +28,10 @@ def edit_resource(type, id = nil, data = {}) def set_additional_attributes @additional_attributes = %w(expression) end + + def set_miq_expression(data) + data["miq_expression"] = data["expression"] + data.delete("expression") + end end end diff --git a/spec/requests/alert_definitions_spec.rb b/spec/requests/alert_definitions_spec.rb index 36c3c68560..04bc711acd 100644 --- a/spec/requests/alert_definitions_spec.rb +++ b/spec/requests/alert_definitions_spec.rb @@ -81,7 +81,7 @@ alert_definition = MiqAlert.find(response.parsed_body["results"].first["id"]) expect(alert_definition).to be_truthy expect(alert_definition.expression.class).to eq(MiqExpression) - expect(alert_definition.expression.exp).to eq(sample_alert_definition["expression"]) + expect(alert_definition.expression.exp).to eq(sample_alert_definition["expression"].deep_symbolize_keys) expect(response.parsed_body["results"].first).to include( "description" => sample_alert_definition["description"], "db" => sample_alert_definition["db"], @@ -91,6 +91,66 @@ ) end + it "creates an alert definition with miq_expression" do + sample_alert_definition = { + "description" => "Test Alert Definition", + "db" => "ContainerNode", + "miq_expression" => { "eval_method" => "dwh_generic", "mode" => "internal", "options" => {} }, + "options" => { "notifications" => {"delay_next_evaluation" => 600, "evm_event" => {} } }, + "enabled" => true + } + api_basic_authorize collection_action_identifier(:alert_definitions, :create) + post(api_alert_definitions_url, :params => sample_alert_definition) + expect(response).to have_http_status(:ok) + alert_definition = MiqAlert.find(response.parsed_body["results"].first["id"]) + expect(alert_definition).to be_truthy + expect(alert_definition.expression.class).to eq(MiqExpression) + expect(alert_definition.expression.exp).to eq(sample_alert_definition["miq_expression"].deep_symbolize_keys) + expect(response.parsed_body["results"].first).to include( + "description" => sample_alert_definition["description"], + "db" => sample_alert_definition["db"], + "expression" => a_hash_including( + "exp" => sample_alert_definition["miq_expression"] + ) + ) + end + + it "creates an alert definition with hash_expression" do + sample_alert_definition = { + "description" => "Test Alert Definition", + "db" => "ContainerNode", + "hash_expression" => { "eval_method" => "dwh_generic", "mode" => "internal", "options" => {} }, + "options" => { "notifications" => {"delay_next_evaluation" => 0, "evm_event" => {} } }, + "enabled" => true + } + api_basic_authorize collection_action_identifier(:alert_definitions, :create) + post(api_alert_definitions_url, :params => sample_alert_definition) + expect(response).to have_http_status(:ok) + alert_definition = MiqAlert.find(response.parsed_body["results"].first["id"]) + expect(alert_definition).to be_truthy + expect(alert_definition.expression.class).to eq(Hash) + expect(alert_definition.expression).to eq(sample_alert_definition["hash_expression"].deep_symbolize_keys) + expect(response.parsed_body["results"].first).to include( + "description" => sample_alert_definition["description"], + "db" => sample_alert_definition["db"], + "expression" => sample_alert_definition["hash_expression"] + ) + end + + it "fails to create an alert definition with more than one expression" do + sample_alert_definition = { + "description" => "Test Alert Definition", + "db" => "ContainerNode", + "hash_expression" => { "eval_method" => "nothing", "mode" => "internal", "options" => {} }, + "miq_expression" => { "eval_method" => "dwh_generic", "mode" => "internal", "options" => {} }, + "options" => { "notifications" => {"delay_next_evaluation" => 600, "evm_event" => {} } }, + "enabled" => true + } + api_basic_authorize collection_action_identifier(:alert_definitions, :create) + post(api_alert_definitions_url, :params => sample_alert_definition) + expect(response).to have_http_status(:bad_request) + end + it "deletes an alert definition via POST" do api_basic_authorize action_identifier(:alert_definitions, :delete, :resource_actions, :post) alert_definition = FactoryGirl.create(:miq_alert) @@ -156,6 +216,77 @@ expect(response.parsed_body).to include(expected) end + it "edits an alert definition with miq_expression" do + api_basic_authorize(action_identifier(:alert_definitions, :edit, :resource_actions, :post)) + alert_definition = FactoryGirl.create( + :miq_alert, + :miq_expression => MiqExpression.new(:eval_method => "mw_heap_used", :mode => "internal", :options => {}), + :options => { :notifications => {:delay_next_evaluation => 0, :evm_event => {} } } + ) + + exp = { :eval_method => "nothing", :mode => "internal", :options => {} } + + post( + api_alert_definition_url(nil, alert_definition), + :params => { + :action => "edit", + :miq_expression => nil, + :hash_expression => exp + } + ) + + expect(response).to have_http_status(:ok) + expect(response.parsed_body).to include("hash_expression" => exp.stringify_keys) + end + + it "edits an alert definition with hash_expression" do + api_basic_authorize(action_identifier(:alert_definitions, :edit, :resource_actions, :post)) + alert_definition = FactoryGirl.create( + :miq_alert, + :hash_expression => { :eval_method => "nothing", :mode => "internal", :options => {} }, + :options => { :notifications => {:delay_next_evaluation => 0, :evm_event => {} } } + ) + + exp = { :eval_method => "mw_heap_used", :mode => "internal", :options => {} } + + post( + api_alert_definition_url(nil, alert_definition), + :params => { + :action => "edit", + :miq_expression => exp, + :hash_expression => nil + } + ) + + expect(response).to have_http_status(:ok) + expect(response.parsed_body).to include( + "miq_expression" => { + "exp" => exp.stringify_keys, + "context_type" => nil + } + ) + end + + it "fails to edit an alert definition with more than one expression" do + api_basic_authorize(action_identifier(:alert_definitions, :edit, :resource_actions, :post)) + alert_definition = FactoryGirl.create( + :miq_alert, + :hash_expression => { :eval_method => "nothing", :mode => "internal", :options => {} }, + :options => { :notifications => {:delay_next_evaluation => 0, :evm_event => {} } } + ) + + post( + api_alert_definition_url(nil, alert_definition), + :params => { + :action => "edit", + :hash_expression => { :eval_method => "event_threshold", :mode => "internal", :options => {} }, + :miq_expression => { :eval_method => "mw_heap_used", :mode => "internal", :options => {} } + } + ) + + expect(response).to have_http_status(:bad_request) + end + it "edits alert definitions" do api_basic_authorize collection_action_identifier(:alert_definitions, :edit) alert_definitions = FactoryGirl.create_list(:miq_alert, 2)