Commit 1405fde1 authored by Peter Leitzen's avatar Peter Leitzen

Merge branch 'add-cilium-parser' into 'master'

Add parser for cilium alerts

See merge request gitlab-org/gitlab!51996
parents 09c2a929 5e74cebe
...@@ -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