Commit 074e31e3 authored by David O'Regan's avatar David O'Regan

Merge branch 'tr-metrics-deprecation-warning' into 'master'

Add Managed Prometheus deprecation warning

See merge request gitlab-org/gitlab!60560
parents f963a7b0 e1055345
......@@ -17,6 +17,7 @@ import { convertToSnakeCase } from '~/lib/utils/text_utility';
import { joinPaths, visitUrl } from '~/lib/utils/url_utility';
import { s__, __ } from '~/locale';
import AlertStatus from '~/vue_shared/alert_details/components/alert_status.vue';
import AlertsDeprecationWarning from '~/vue_shared/components/alerts_deprecation_warning.vue';
import {
tdClass,
thClass,
......@@ -96,6 +97,7 @@ export default {
severityLabels: SEVERITY_LEVELS,
statusTabs: ALERTS_STATUS_TABS,
components: {
AlertsDeprecationWarning,
GlAlert,
GlLoadingIcon,
GlTable,
......@@ -273,6 +275,8 @@ export default {
</gl-sprintf>
</gl-alert>
<alerts-deprecation-warning />
<paginated-table-with-search-and-tabs
:show-error-msg="showErrorMsg"
:i18n="$options.i18n"
......
......@@ -23,6 +23,7 @@ export default () => {
assigneeUsernameQuery,
alertManagementEnabled,
userCanEnableAlertManagement,
hasManagedPrometheus,
} = domEl.dataset;
const apolloProvider = new VueApollo({
......@@ -64,6 +65,7 @@ export default () => {
alertManagementEnabled: parseBoolean(alertManagementEnabled),
trackAlertStatusUpdateOptions: PAGE_CONFIG.OPERATIONS.TRACK_ALERT_STATUS_UPDATE_OPTIONS,
userCanEnableAlertManagement: parseBoolean(userCanEnableAlertManagement),
hasManagedPrometheus: parseBoolean(hasManagedPrometheus),
},
apolloProvider,
render(createElement) {
......
......@@ -8,6 +8,7 @@ import invalidUrl from '~/lib/utils/invalid_url';
import { ESC_KEY } from '~/lib/utils/keys';
import { mergeUrlParams, updateHistory } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
import AlertsDeprecationWarning from '~/vue_shared/components/alerts_deprecation_warning.vue';
import { defaultTimeRange } from '~/vue_shared/constants';
import TrackEventDirective from '~/vue_shared/directives/track_event';
import { metricStates, keyboardShortcutKeys } from '../constants';
......@@ -28,6 +29,7 @@ import VariablesSection from './variables_section.vue';
export default {
components: {
AlertsDeprecationWarning,
VueDraggable,
DashboardHeader,
DashboardPanel,
......@@ -394,6 +396,8 @@ export default {
<template>
<div class="prometheus-graphs" data-qa-selector="prometheus_graphs">
<alerts-deprecation-warning />
<dashboard-header
v-if="showHeader"
ref="prometheusGraphsHeader"
......
......@@ -12,7 +12,10 @@ export default (props = {}) => {
if (el && el.dataset) {
const { metricsDashboardBasePath, ...dataset } = el.dataset;
const { initState, dataProps } = stateAndPropsFromDataset(dataset);
const {
initState,
dataProps: { hasManagedPrometheus, ...dataProps },
} = stateAndPropsFromDataset(dataset);
const store = createStore(initState);
const router = createRouter(metricsDashboardBasePath);
......@@ -21,6 +24,7 @@ export default (props = {}) => {
el,
store,
router,
provide: { hasManagedPrometheus },
data() {
return {
dashboardProps: { ...dataProps, ...props },
......
......@@ -41,6 +41,7 @@ export const stateAndPropsFromDataset = (dataset = {}) => {
dataProps.hasMetrics = parseBoolean(dataProps.hasMetrics);
dataProps.customMetricsAvailable = parseBoolean(dataProps.customMetricsAvailable);
dataProps.prometheusAlertsAvailable = parseBoolean(dataProps.prometheusAlertsAvailable);
dataProps.hasManagedPrometheus = parseBoolean(dataProps.hasManagedPrometheus);
return {
initState: {
......
<script>
import { GlAlert, GlLink, GlSprintf } from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper';
import { s__ } from '~/locale';
export default {
components: {
GlAlert,
GlLink,
GlSprintf,
},
inject: ['hasManagedPrometheus'],
i18n: {
alertsDeprecationText: s__(
'Metrics|GitLab-managed Prometheus is deprecated and %{linkStart}scheduled for removal%{linkEnd}. Following this removal, your existing alerts will continue to function as part of the new cluster integration. However, you will no longer be able to add new alerts or edit existing alerts from the metrics dashboard.',
),
},
methods: {
helpPagePath,
},
};
</script>
<template>
<gl-alert v-if="hasManagedPrometheus" variant="warning" class="my-2">
<gl-sprintf :message="$options.i18n.alertsDeprecationText">
<template #link="{ content }">
<gl-link
:href="
helpPagePath('operations/metrics/alerts.html', {
anchor: 'managed-prometheus-instances',
})
"
target="_blank"
>
<span>{{ content }}</span>
</gl-link>
</template>
</gl-sprintf>
</gl-alert>
</template>
......@@ -62,7 +62,8 @@ module EnvironmentsHelper
'validate_query_path' => validate_query_project_prometheus_metrics_path(project),
'custom_metrics_available' => "#{custom_metrics_available?(project)}",
'prometheus_alerts_available' => "#{can?(current_user, :read_prometheus_alerts, project)}",
'dashboard_timezone' => project.metrics_setting_dashboard_timezone.to_s.upcase
'dashboard_timezone' => project.metrics_setting_dashboard_timezone.to_s.upcase,
'has_managed_prometheus' => has_managed_prometheus?(project).to_s
}
end
......@@ -78,6 +79,10 @@ module EnvironmentsHelper
}
end
def has_managed_prometheus?(project)
project.prometheus_service&.prometheus_available? == true
end
def metrics_dashboard_base_path(environment, project)
# This is needed to support our transition from environment scoped metric paths to project scoped.
if project
......
......@@ -10,6 +10,7 @@ module Projects::AlertManagementHelper
'empty-alert-svg-path' => image_path('illustrations/alert-management-empty-state.svg'),
'user-can-enable-alert-management' => can?(current_user, :admin_operations, project).to_s,
'alert-management-enabled' => alert_management_enabled?(project).to_s,
'has-managed-prometheus' => has_managed_prometheus?(project).to_s,
'text-query': params[:search],
'assignee-username-query': params[:assignee_username]
}
......@@ -27,6 +28,10 @@ module Projects::AlertManagementHelper
private
def has_managed_prometheus?(project)
project.prometheus_service&.prometheus_available? == true
end
def alert_management_enabled?(project)
!!(
project.alert_management_alerts.any? ||
......
---
title: Add Managed Prometheus deprecation warning
merge_request: 60560
author:
type: deprecated
......@@ -20886,6 +20886,9 @@ msgstr ""
msgid "Metrics|For grouping similar metrics"
msgstr ""
msgid "Metrics|GitLab-managed Prometheus is deprecated and %{linkStart}scheduled for removal%{linkEnd}. Following this removal, your existing alerts will continue to function as part of the new cluster integration. However, you will no longer be able to add new alerts or edit existing alerts from the metrics dashboard."
msgstr ""
msgid "Metrics|Invalid time range, please verify."
msgstr ""
......
......@@ -7,6 +7,7 @@ import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import mockAlerts from 'jest/vue_shared/alert_details/mocks/alerts.json';
import AlertManagementTable from '~/alert_management/components/alert_management_table.vue';
import { visitUrl } from '~/lib/utils/url_utility';
import AlertDeprecationWarning from '~/vue_shared/components/alerts_deprecation_warning.vue';
import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import defaultProvideValues from '../mocks/alerts_provide_config.json';
......@@ -14,6 +15,7 @@ import defaultProvideValues from '../mocks/alerts_provide_config.json';
jest.mock('~/lib/utils/url_utility', () => ({
visitUrl: jest.fn().mockName('visitUrlMock'),
joinPaths: jest.requireActual('~/lib/utils/url_utility').joinPaths,
setUrlFragment: jest.requireActual('~/lib/utils/url_utility').setUrlFragment,
}));
describe('AlertManagementTable', () => {
......@@ -39,6 +41,8 @@ describe('AlertManagementTable', () => {
resolved: 11,
all: 26,
};
const findDeprecationNotice = () =>
wrapper.findComponent(AlertDeprecationWarning).findComponent(GlAlert);
function mountComponent({ provide = {}, data = {}, loading = false, stubs = {} } = {}) {
wrapper = extendedWrapper(
......@@ -47,6 +51,7 @@ describe('AlertManagementTable', () => {
...defaultProvideValues,
alertManagementEnabled: true,
userCanEnableAlertManagement: true,
hasManagedPrometheus: false,
...provide,
},
data() {
......@@ -234,6 +239,20 @@ describe('AlertManagementTable', () => {
expect(visitUrl).toHaveBeenCalledWith('/1527542/details', true);
});
describe('deprecation notice', () => {
it('shows the deprecation notice when available', () => {
mountComponent({ provide: { hasManagedPrometheus: true } });
expect(findDeprecationNotice().exists()).toBe(true);
});
it('hides the deprecation notice when not available', () => {
mountComponent();
expect(findDeprecationNotice().exists()).toBe(false);
});
});
describe('alert issue links', () => {
beforeEach(() => {
mountComponent({
......
......@@ -9,6 +9,8 @@ exports[`Dashboard template matches the default snapshot 1`] = `
metricsendpoint="/monitoring/monitor-project/-/environments/1/additional_metrics.json"
prometheusstatus=""
>
<alerts-deprecation-warning-stub />
<div
class="prometheus-graphs-header d-sm-flex flex-sm-wrap pt-2 pr-1 pb-0 pl-2 border-bottom bg-gray-light"
>
......
......@@ -28,6 +28,7 @@ describe('dashboard invalid url parameters', () => {
},
},
options,
provide: { hasManagedPrometheus: false },
});
};
......
import { GlAlert } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import VueDraggable from 'vuedraggable';
......@@ -7,7 +8,6 @@ import axios from '~/lib/utils/axios_utils';
import { ESC_KEY } from '~/lib/utils/keys';
import { objectToQuery } from '~/lib/utils/url_utility';
import Dashboard from '~/monitoring/components/dashboard.vue';
import DashboardHeader from '~/monitoring/components/dashboard_header.vue';
import DashboardPanel from '~/monitoring/components/dashboard_panel.vue';
import EmptyState from '~/monitoring/components/empty_state.vue';
......@@ -17,6 +17,7 @@ import LinksSection from '~/monitoring/components/links_section.vue';
import { dashboardEmptyStates, metricStates } from '~/monitoring/constants';
import { createStore } from '~/monitoring/stores';
import * as types from '~/monitoring/stores/mutation_types';
import AlertDeprecationWarning from '~/vue_shared/components/alerts_deprecation_warning.vue';
import {
metricsDashboardViewModel,
metricsDashboardPanelCount,
......@@ -46,6 +47,7 @@ describe('Dashboard', () => {
stubs: {
DashboardHeader,
},
provide: { hasManagedPrometheus: false },
...options,
});
};
......@@ -59,6 +61,9 @@ describe('Dashboard', () => {
'dashboard-panel': true,
'dashboard-header': DashboardHeader,
},
provide: {
hasManagedPrometheus: false,
},
...options,
});
};
......@@ -812,4 +817,25 @@ describe('Dashboard', () => {
expect(dashboardPanel.exists()).toBe(true);
});
});
describe('deprecation notice', () => {
beforeEach(() => {
setupStoreWithData(store);
});
const findDeprecationNotice = () =>
wrapper.find(AlertDeprecationWarning).findComponent(GlAlert);
it('shows the deprecation notice when available', () => {
createMountedWrapper({}, { provide: { hasManagedPrometheus: true } });
expect(findDeprecationNotice().exists()).toBe(true);
});
it('hides the deprecation notice when not available', () => {
createMountedWrapper();
expect(findDeprecationNotice().exists()).toBe(false);
});
});
});
......@@ -31,6 +31,7 @@ describe('dashboard invalid url parameters', () => {
store,
stubs: { 'graph-group': true, 'dashboard-panel': true, 'dashboard-header': DashboardHeader },
...options,
provide: { hasManagedPrometheus: false },
});
};
......
......@@ -20,6 +20,8 @@ const MockApp = {
template: `<router-view :dashboard-props="dashboardProps"/>`,
};
const provide = { hasManagedPrometheus: false };
describe('Monitoring router', () => {
let router;
let store;
......@@ -37,6 +39,7 @@ describe('Monitoring router', () => {
localVue,
store,
router,
provide,
});
};
......
import { GlAlert, GlLink } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import AlertDeprecationWarning from '~/vue_shared/components/alerts_deprecation_warning.vue';
describe('AlertDetails', () => {
let wrapper;
function mountComponent(hasManagedPrometheus = false) {
wrapper = mount(AlertDeprecationWarning, {
provide: {
hasManagedPrometheus,
},
});
}
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findAlert = () => wrapper.findComponent(GlAlert);
const findLink = () => wrapper.findComponent(GlLink);
describe('Alert details', () => {
describe('with no manual prometheus', () => {
beforeEach(() => {
mountComponent();
});
it('renders nothing', () => {
expect(findAlert().exists()).toBe(false);
});
});
describe('with manual prometheus', () => {
beforeEach(() => {
mountComponent(true);
});
it('renders a deprecation notice', () => {
expect(findAlert().text()).toContain('GitLab-managed Prometheus is deprecated');
expect(findLink().attributes('href')).toContain(
'operations/metrics/alerts.html#managed-prometheus-instances',
);
});
});
});
});
......@@ -45,7 +45,8 @@ RSpec.describe EnvironmentsHelper do
'custom_dashboard_base_path' => Gitlab::Metrics::Dashboard::RepoDashboardFinder::DASHBOARD_ROOT,
'operations_settings_path' => project_settings_operations_path(project),
'can_access_operations_settings' => 'true',
'panel_preview_endpoint' => project_metrics_dashboards_builder_path(project, format: :json)
'panel_preview_endpoint' => project_metrics_dashboards_builder_path(project, format: :json),
'has_managed_prometheus' => 'false'
)
end
......@@ -120,6 +121,52 @@ RSpec.describe EnvironmentsHelper do
end
end
end
context 'has_managed_prometheus' do
context 'without prometheus service' do
it "doesn't have managed prometheus" do
expect(metrics_data).to include(
'has_managed_prometheus' => 'false'
)
end
end
context 'with prometheus service' do
let_it_be(:prometheus_service) { create(:prometheus_service, project: project) }
context 'when manual prometheus service is active' do
it "doesn't have managed prometheus" do
prometheus_service.update!(manual_configuration: true)
expect(metrics_data).to include(
'has_managed_prometheus' => 'false'
)
end
end
context 'when prometheus service is inactive' do
it "doesn't have managed prometheus" do
prometheus_service.update!(manual_configuration: false)
expect(metrics_data).to include(
'has_managed_prometheus' => 'false'
)
end
end
context 'when a cluster prometheus is available' do
let(:cluster) { create(:cluster, projects: [project]) }
it 'has managed prometheus' do
create(:clusters_applications_prometheus, :installed, cluster: cluster)
expect(metrics_data).to include(
'has_managed_prometheus' => 'true'
)
end
end
end
end
end
describe '#custom_metrics_available?' do
......
......@@ -34,6 +34,7 @@ RSpec.describe Projects::AlertManagementHelper do
'empty-alert-svg-path' => match_asset_path('/assets/illustrations/alert-management-empty-state.svg'),
'user-can-enable-alert-management' => 'true',
'alert-management-enabled' => 'false',
'has-managed-prometheus' => 'false',
'text-query': nil,
'assignee-username-query': nil
)
......@@ -43,23 +44,51 @@ RSpec.describe Projects::AlertManagementHelper do
context 'with prometheus service' do
let_it_be(:prometheus_service) { create(:prometheus_service, project: project) }
context 'when prometheus service is active' do
it 'enables alert management' do
context 'when manual prometheus service is active' do
it "enables alert management and doesn't show managed prometheus" do
prometheus_service.update!(manual_configuration: true)
expect(data).to include(
'alert-management-enabled' => 'true'
)
expect(data).to include(
'has-managed-prometheus' => 'false'
)
end
end
context 'when a cluster prometheus is available' do
let(:cluster) { create(:cluster, projects: [project]) }
it 'has managed prometheus' do
create(:clusters_applications_prometheus, :installed, cluster: cluster)
expect(data).to include(
'has-managed-prometheus' => 'true'
)
end
end
context 'when prometheus service is inactive' do
it 'disables alert management' do
it 'disables alert management and hides managed prometheus' do
prometheus_service.update!(manual_configuration: false)
expect(data).to include(
'alert-management-enabled' => 'false'
)
expect(data).to include(
'has-managed-prometheus' => 'false'
)
end
end
end
context 'without prometheus service' do
it "doesn't have managed prometheus" do
expect(data).to include(
'has-managed-prometheus' => 'false'
)
end
end
context 'with http integration' do
......
......@@ -61,6 +61,7 @@ describe('Dashboard', () => {
showPanels: true,
},
store,
provide: { hasManagedPrometheus: false },
});
setupStoreWithData(component.$store);
......
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