Commit 5e74cebe authored by Can Eldem's avatar Can Eldem Committed by Peter Leitzen

Add parser for cilium alerts

Cilium alerts were using generic parser
This parser is created to parsing alert coming from KAS
parent 2fc8048c
...@@ -4,7 +4,6 @@ module AlertManagement ...@@ -4,7 +4,6 @@ module AlertManagement
# Create alerts coming K8 through gitlab-agent # Create alerts coming K8 through gitlab-agent
class NetworkAlertService class NetworkAlertService
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
include ::IncidentManagement::Settings
MONITORING_TOOL = Gitlab::AlertManagement::Payload::MONITORING_TOOLS.fetch(:cilium) MONITORING_TOOL = Gitlab::AlertManagement::Payload::MONITORING_TOOLS.fetch(:cilium)
...@@ -18,8 +17,6 @@ module AlertManagement ...@@ -18,8 +17,6 @@ module AlertManagement
def execute def execute
return bad_request unless valid_payload_size? return bad_request unless valid_payload_size?
# Not meant to run with a user, but with a agent
# See https://gitlab.com/gitlab-org/gitlab/-/issues/291986
process_request process_request
return bad_request unless alert.persisted? return bad_request unless alert.persisted?
...@@ -80,14 +77,9 @@ module AlertManagement ...@@ -80,14 +77,9 @@ module AlertManagement
AlertManagement::Alert.new(**incoming_payload.alert_params, domain: :threat_monitoring, ended_at: nil) AlertManagement::Alert.new(**incoming_payload.alert_params, domain: :threat_monitoring, ended_at: nil)
end end
# https://gitlab.com/gitlab-org/gitlab/-/issues/292034
def incoming_payload def incoming_payload
strong_memoize(:incoming_payload) do strong_memoize(:incoming_payload) do
Gitlab::AlertManagement::Payload.parse( Gitlab::AlertManagement::Payload.parse(project, payload, monitoring_tool: MONITORING_TOOL)
project,
payload,
monitoring_tool: MONITORING_TOOL
)
end end
end end
......
# frozen_string_literal: true
module EE
module Gitlab
module AlertManagement
module Payload
extend ActiveSupport::Concern
class_methods do
extend ::Gitlab::Utils::Override
private
override :payload_class_for
def payload_class_for(monitoring_tool:, payload:)
if monitoring_tool == ::Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:cilium]
::Gitlab::AlertManagement::Payload::Cilium
else
super
end
end
end
end
end
end
end
# frozen_string_literal: true
module Gitlab
module AlertManagement
module Payload
class Cilium < Gitlab::AlertManagement::Payload::Generic
DEFAULT_TITLE = 'New: Alert'
attribute :description, paths: %w(flow dropReasonDesc)
attribute :title, paths: %w(ciliumNetworkPolicy metadata name), fallback: -> { DEFAULT_TITLE }
attribute :gitlab_fingerprint, paths: %w(fingerprint)
def monitoring_tool
Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:cilium]
end
end
end
end
end
# frozen_string_literal: true
FactoryBot.define do
factory :network_alert_payload, class: Hash do
initialize_with do
{
fingerprint: 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3',
flow: {
dropReasonDesc: "POLICY_DENIED"
},
ciliumNetworkPolicy: {
kind: 'bla',
apiVersion: 'bla',
metadata: {
name: 'Cilium Alert',
generateName: 'generated NAme',
namespace: 'LocalGitlab',
selfLink: 'www.gitlab.com',
uid: '2d931510-d99f-494a-8c67-87feb05e1594',
resourceVersion: '23',
deletionGracePeriodSeconds: 42,
clusterName: 'TestCluster'
},
status: {}
}
}.with_indifferent_access
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::AlertManagement::Payload do
describe '#parse' do
let_it_be(:project) { build_stubbed(:project) }
let(:payload) { {} }
context 'with the payload specifing cilium as monitoring tool' do
before do
stub_licensed_features(cilium_alerts: true)
end
subject { described_class.parse(project, payload) }
context 'with the payload specifying an unknown tool' do
let(:payload) { { 'monitoring_tool' => 'Cilium' } }
it { is_expected.to be_a Gitlab::AlertManagement::Payload::Cilium }
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::AlertManagement::Payload::Cilium do
let_it_be(:project) { build_stubbed(:project) }
let(:raw_payload) { build(:network_alert_payload).to_json }
let(:parsed_payload) do
described_class.new(project: project, payload: Gitlab::Json.parse(raw_payload))
end
it 'parses cilium specific fields' do
expect(parsed_payload.title).to eq('Cilium Alert')
expect(parsed_payload.description).to eq('POLICY_DENIED')
expect(parsed_payload.gitlab_fingerprint).to eq('a94a8fe5ccb19ba61c4c0873d391e987982fbbd3')
end
end
...@@ -71,8 +71,7 @@ RSpec.describe API::Internal::Kubernetes do ...@@ -71,8 +71,7 @@ RSpec.describe API::Internal::Kubernetes do
{ {
alert: { alert: {
title: 'minimal', title: 'minimal',
message: 'network problem', message: 'network problem'
evalMatches: [{ value: 1, metric: 'Count', tags: {} }]
} }
} }
end end
......
...@@ -37,20 +37,7 @@ RSpec.describe AlertManagement::NetworkAlertService do ...@@ -37,20 +37,7 @@ RSpec.describe AlertManagement::NetworkAlertService do
end end
context 'with valid payload' do context 'with valid payload' do
let(:payload_raw) do let(:payload_raw) { build(:network_alert_payload) }
{
title: 'alert title',
start_time: starts_at.rfc3339,
end_time: ended_at&.rfc3339,
severity: 'low',
monitoring_tool: tool,
service: 'GitLab Test Suite',
description: 'Very detailed description',
hosts: %w[1.1.1.1 2.2.2.2],
fingerprint: fingerprint,
gitlab_environment_name: environment.name
}.with_indifferent_access
end
let(:payload) { ActionController::Parameters.new(payload_raw).permit! } let(:payload) { ActionController::Parameters.new(payload_raw).permit! }
...@@ -59,12 +46,31 @@ RSpec.describe AlertManagement::NetworkAlertService do ...@@ -59,12 +46,31 @@ RSpec.describe AlertManagement::NetworkAlertService do
.with_indifferent_access .with_indifferent_access
end end
it_behaves_like 'creates an alert management alert' it 'create alert and assigns properties' do
it_behaves_like 'assigns the alert properties' subject
expect(last_alert_attributes).to match(a_hash_including({
description: 'POLICY_DENIED',
domain: 'threat_monitoring',
ended_at: nil,
environment_id: nil,
events: 1,
fingerprint: 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3',
hosts: [],
issue_id: nil,
monitoring_tool: 'Cilium',
payload: payload_raw.with_indifferent_access,
project_id: project.id,
prometheus_alert_id: nil,
service: nil,
severity: 'critical',
title: 'Cilium Alert'
}))
end
it 'creates a system note corresponding to alert creation' do it 'creates a system note corresponding to alert creation' do
expect { subject }.to change(Note, :count).by(1) expect { subject }.to change(Note, :count).by(1)
expect(Note.last.note).to include(payload_raw.fetch(:monitoring_tool)) expect(Note.last.note).to include('Cilium')
end end
context 'when alert exists' do context 'when alert exists' do
...@@ -116,7 +122,6 @@ RSpec.describe AlertManagement::NetworkAlertService do ...@@ -116,7 +122,6 @@ RSpec.describe AlertManagement::NetworkAlertService do
end end
it_behaves_like 'creates an alert management alert' it_behaves_like 'creates an alert management alert'
it_behaves_like 'assigns the alert properties'
end end
context 'existing alert is ignored' do context 'existing alert is ignored' do
...@@ -147,13 +152,6 @@ RSpec.describe AlertManagement::NetworkAlertService do ...@@ -147,13 +152,6 @@ RSpec.describe AlertManagement::NetworkAlertService do
it_behaves_like 'adds an alert management alert event' it_behaves_like 'adds an alert management alert event'
end end
end end
context 'end time given' do
let(:ended_at) { Time.current }
it_behaves_like 'creates an alert management alert'
it_behaves_like 'assigns the alert properties'
end
end end
context 'with overlong payload' do context 'with overlong payload' do
......
...@@ -47,3 +47,5 @@ module Gitlab ...@@ -47,3 +47,5 @@ module Gitlab
end end
end end
end end
Gitlab::AlertManagement::Payload.prepend_if_ee('EE::Gitlab::AlertManagement::Payload')
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment