Commit 6c275701 authored by Thong Kuah's avatar Thong Kuah

Disable automatic setup of alerts for Prometheus cluster integration

This may be a feature we support later but not currently.

Changelog: changed
parent a4a77904
...@@ -44,6 +44,10 @@ module Clusters ...@@ -44,6 +44,10 @@ module Clusters
end end
end end
def managed_prometheus?
!externally_installed? && !uninstalled?
end
def updated_since?(timestamp) def updated_since?(timestamp)
last_update_started_at && last_update_started_at &&
last_update_started_at > timestamp && last_update_started_at > timestamp &&
...@@ -70,6 +74,7 @@ module Clusters ...@@ -70,6 +74,7 @@ module Clusters
) )
end end
# Deprecated, to be removed in %14.0 as part of https://gitlab.com/groups/gitlab-org/-/epics/4280
def patch_command(values) def patch_command(values)
helm_command_module::PatchCommand.new( helm_command_module::PatchCommand.new(
name: name, name: name,
......
...@@ -26,6 +26,11 @@ module PrometheusAdapter ...@@ -26,6 +26,11 @@ module PrometheusAdapter
} }
end end
# Overridden in app/models/clusters/applications/prometheus.rb
def managed_prometheus?
false
end
# This is a light-weight check if a prometheus client is properly configured. # This is a light-weight check if a prometheus client is properly configured.
def configured? def configured?
raise NotImplemented raise NotImplemented
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
module Clusters module Clusters
module Applications module Applications
# Deprecated, to be removed in %14.0 as part of https://gitlab.com/groups/gitlab-org/-/epics/4280
class PrometheusUpdateService < BaseHelmService class PrometheusUpdateService < BaseHelmService
attr_accessor :project attr_accessor :project
...@@ -11,6 +12,8 @@ module Clusters ...@@ -11,6 +12,8 @@ module Clusters
end end
def execute def execute
raise NotImplementedError, 'Externally installed prometheus should not be modified!' unless app.managed_prometheus?
app.make_updating! app.make_updating!
helm_api.update(patch_command(values)) helm_api.update(patch_command(values))
......
...@@ -14,6 +14,7 @@ module Clusters ...@@ -14,6 +14,7 @@ module Clusters
def execute def execute
return unless application return unless application
return unless application.managed_prometheus?
if recently_scheduled? if recently_scheduled?
worker_class.perform_in(BACKOFF_DELAY, application.name, application.id, project.id, Time.current) worker_class.perform_in(BACKOFF_DELAY, application.name, application.id, project.id, Time.current)
......
# frozen_string_literal: true # frozen_string_literal: true
# Deprecated, to be removed in %14.0 as part of https://gitlab.com/groups/gitlab-org/-/epics/4280
class ClusterUpdateAppWorker # rubocop:disable Scalability/IdempotentWorker class ClusterUpdateAppWorker # rubocop:disable Scalability/IdempotentWorker
UpdateAlreadyInProgressError = Class.new(StandardError) UpdateAlreadyInProgressError = Class.new(StandardError)
...@@ -35,6 +36,7 @@ class ClusterUpdateAppWorker # rubocop:disable Scalability/IdempotentWorker ...@@ -35,6 +36,7 @@ class ClusterUpdateAppWorker # rubocop:disable Scalability/IdempotentWorker
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
def update_prometheus(app, scheduled_time, project) def update_prometheus(app, scheduled_time, project)
return unless app.managed_prometheus?
return if app.updated_since?(scheduled_time) return if app.updated_since?(scheduled_time)
return if app.update_in_progress? return if app.update_in_progress?
......
---
title: Disable automatic setup of alerts for Prometheus cluster integration
merge_request: 58853
author:
type: changed
...@@ -49,6 +49,10 @@ as soon as the alert fires: ...@@ -49,6 +49,10 @@ as soon as the alert fires:
![Linked Runbook in charts](img/linked_runbooks_on_charts.png) ![Linked Runbook in charts](img/linked_runbooks_on_charts.png)
## Prometheus cluster integrations
Alerts are not currently supported for [Prometheus cluster integrations](../../user/clusters/integrations.md).
## External Prometheus instances ## External Prometheus instances
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9258) in GitLab Ultimate 11.8. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9258) in GitLab Ultimate 11.8.
......
...@@ -20,6 +20,9 @@ You can integrate your Kubernetes cluster with ...@@ -20,6 +20,9 @@ You can integrate your Kubernetes cluster with
[Prometheus](https://prometheus.io/) for monitoring key metrics of your [Prometheus](https://prometheus.io/) for monitoring key metrics of your
apps directly from the GitLab UI. apps directly from the GitLab UI.
[Alerts](../../operations/metrics/alerts.md) are not currently
supported.
Once enabled, you will see metrics from services available in the Once enabled, you will see metrics from services available in the
[metrics library](../project/integrations/prometheus_library/index.md). [metrics library](../project/integrations/prometheus_library/index.md).
......
...@@ -65,6 +65,26 @@ RSpec.describe Clusters::Applications::Prometheus do ...@@ -65,6 +65,26 @@ RSpec.describe Clusters::Applications::Prometheus do
end end
end end
describe '#managed_prometheus?' do
subject { prometheus.managed_prometheus? }
let(:prometheus) { build(:clusters_applications_prometheus) }
it { is_expected.to be_truthy }
context 'externally installed' do
let(:prometheus) { build(:clusters_applications_prometheus, :externally_installed) }
it { is_expected.to be_falsey }
end
context 'uninstalled' do
let(:prometheus) { build(:clusters_applications_prometheus, :uninstalled) }
it { is_expected.to be_falsey }
end
end
describe '#can_uninstall?' do describe '#can_uninstall?' do
let(:prometheus) { create(:clusters_applications_prometheus) } let(:prometheus) { create(:clusters_applications_prometheus) }
......
...@@ -9,83 +9,102 @@ RSpec.describe Clusters::Applications::PrometheusUpdateService do ...@@ -9,83 +9,102 @@ RSpec.describe Clusters::Applications::PrometheusUpdateService do
let(:cluster) { create(:cluster, :provided_by_user, :with_installed_helm, projects: [project]) } let(:cluster) { create(:cluster, :provided_by_user, :with_installed_helm, projects: [project]) }
let(:application) { create(:clusters_applications_prometheus, :installed, cluster: cluster) } let(:application) { create(:clusters_applications_prometheus, :installed, cluster: cluster) }
let(:empty_alerts_values_update_yaml) { "---\nalertmanager:\n enabled: false\nserverFiles:\n alerts: {}\n" } let(:empty_alerts_values_update_yaml) { "---\nalertmanager:\n enabled: false\nserverFiles:\n alerts: {}\n" }
let!(:patch_command) { application.patch_command(empty_alerts_values_update_yaml) }
let(:helm_client) { instance_double(::Gitlab::Kubernetes::Helm::API) } let(:helm_client) { instance_double(::Gitlab::Kubernetes::Helm::API) }
subject(:service) { described_class.new(application, project) } subject(:service) { described_class.new(application, project) }
before do context 'when prometheus is a Clusters::Integrations::Prometheus' do
allow(service).to receive(:patch_command).with(empty_alerts_values_update_yaml).and_return(patch_command) let(:application) { create(:clusters_integrations_prometheus, cluster: cluster) }
allow(service).to receive(:helm_api).and_return(helm_client)
it 'raises NotImplementedError' do
expect { service.execute }.to raise_error(NotImplementedError)
end
end end
context 'when there are no errors' do context 'when prometheus is externally installed' do
before do let(:application) { create(:clusters_applications_prometheus, :externally_installed, cluster: cluster) }
expect(helm_client).to receive(:update).with(patch_command)
allow(::ClusterWaitForAppUpdateWorker) it 'raises NotImplementedError' do
.to receive(:perform_in) expect { service.execute }.to raise_error(NotImplementedError)
.and_return(nil)
end end
end
it 'make the application updating' do context 'when prometheus is a Clusters::Applications::Prometheus' do
expect(application.cluster).not_to be_nil let!(:patch_command) { application.patch_command(empty_alerts_values_update_yaml) }
service.execute
expect(application).to be_updating before do
allow(service).to receive(:patch_command).with(empty_alerts_values_update_yaml).and_return(patch_command)
allow(service).to receive(:helm_api).and_return(helm_client)
end end
it 'updates current config' do context 'when there are no errors' do
prometheus_config_service = spy(:prometheus_config_service) before do
expect(helm_client).to receive(:update).with(patch_command)
expect(Clusters::Applications::PrometheusConfigService) allow(::ClusterWaitForAppUpdateWorker)
.to receive(:new) .to receive(:perform_in)
.with(project, cluster, application) .and_return(nil)
.and_return(prometheus_config_service) end
expect(prometheus_config_service) it 'make the application updating' do
.to receive(:execute) expect(application.cluster).not_to be_nil
.and_return(YAML.safe_load(empty_alerts_values_update_yaml))
service.execute service.execute
end
it 'schedules async update status check' do expect(application).to be_updating
expect(::ClusterWaitForAppUpdateWorker).to receive(:perform_in).once end
service.execute it 'updates current config' do
end prometheus_config_service = spy(:prometheus_config_service)
end
context 'when k8s cluster communication fails' do expect(Clusters::Applications::PrometheusConfigService)
before do .to receive(:new)
error = ::Kubeclient::HttpError.new(500, 'system failure', nil) .with(project, cluster, application)
allow(helm_client).to receive(:update).and_raise(error) .and_return(prometheus_config_service)
end
expect(prometheus_config_service)
.to receive(:execute)
.and_return(YAML.safe_load(empty_alerts_values_update_yaml))
it 'make the application update errored' do service.execute
service.execute end
expect(application).to be_update_errored it 'schedules async update status check' do
expect(application.status_reason).to match(/kubernetes error:/i) expect(::ClusterWaitForAppUpdateWorker).to receive(:perform_in).once
service.execute
end
end end
end
context 'when application cannot be persisted' do context 'when k8s cluster communication fails' do
let(:application) { build(:clusters_applications_prometheus, :installed) } before do
error = ::Kubeclient::HttpError.new(500, 'system failure', nil)
allow(helm_client).to receive(:update).and_raise(error)
end
before do it 'make the application update errored' do
allow(application).to receive(:make_updating!).once service.execute
.and_raise(ActiveRecord::RecordInvalid.new(application))
expect(application).to be_update_errored
expect(application.status_reason).to match(/kubernetes error:/i)
end
end end
it 'make the application update errored' do context 'when application cannot be persisted' do
expect(helm_client).not_to receive(:update) let(:application) { build(:clusters_applications_prometheus, :installed) }
before do
allow(application).to receive(:make_updating!).once
.and_raise(ActiveRecord::RecordInvalid.new(application))
end
it 'make the application update errored' do
expect(helm_client).not_to receive(:update)
service.execute service.execute
expect(application).to be_update_errored expect(application).to be_update_errored
end
end end
end end
end end
......
...@@ -10,6 +10,32 @@ RSpec.describe Clusters::Applications::ScheduleUpdateService do ...@@ -10,6 +10,32 @@ RSpec.describe Clusters::Applications::ScheduleUpdateService do
freeze_time { example.run } freeze_time { example.run }
end end
context 'when the application is a Clusters::Integrations::Prometheus' do
let(:application) { create(:clusters_integrations_prometheus) }
it 'does nothing' do
service = described_class.new(application, project)
expect(::ClusterUpdateAppWorker).not_to receive(:perform_in)
expect(::ClusterUpdateAppWorker).not_to receive(:perform_async)
service.execute
end
end
context 'when the application is externally installed' do
let(:application) { create(:clusters_applications_prometheus, :externally_installed) }
it 'does nothing' do
service = described_class.new(application, project)
expect(::ClusterUpdateAppWorker).not_to receive(:perform_in)
expect(::ClusterUpdateAppWorker).not_to receive(:perform_async)
service.execute
end
end
context 'when application is able to be updated' do context 'when application is able to be updated' do
context 'when the application was recently scheduled' do context 'when the application was recently scheduled' do
it 'schedules worker with a backoff delay' do it 'schedules worker with a backoff delay' do
......
...@@ -46,6 +46,16 @@ RSpec.describe ClusterUpdateAppWorker do ...@@ -46,6 +46,16 @@ RSpec.describe ClusterUpdateAppWorker do
subject.perform(application.name, application.id, project.id, Time.current) subject.perform(application.name, application.id, project.id, Time.current)
end end
context 'application is externally installed' do
it 'does not execute PrometheusUpdateService' do
application = create(:clusters_applications_prometheus, :externally_installed)
expect(prometheus_update_service).not_to receive(:execute)
subject.perform(application.name, application.id, project.id, Time.current)
end
end
context 'with exclusive lease' do context 'with exclusive lease' do
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let(:application) { create(:clusters_applications_prometheus, :installed) } let(:application) { create(:clusters_applications_prometheus, :installed) }
......
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