Commit 790793d9 authored by Shinya Maeda's avatar Shinya Maeda

Merge branch 'mwaw/215224-make-dashboard-annotations-generally-available' into 'master'

Make Dashboard Annotations Generally Available

See merge request gitlab-org/gitlab!30371
parents d18b4036 f2c0274a
......@@ -13,11 +13,7 @@ import trackDashboardLoad from '../monitoring_tracking_helper';
import getEnvironments from '../queries/getEnvironments.query.graphql';
import getAnnotations from '../queries/getAnnotations.query.graphql';
import statusCodes from '../../lib/utils/http_status';
import {
backOff,
convertObjectPropsToCamelCase,
isFeatureFlagEnabled,
} from '../../lib/utils/common_utils';
import { backOff, convertObjectPropsToCamelCase } from '../../lib/utils/common_utils';
import { s__, sprintf } from '../../locale';
import {
......@@ -116,14 +112,7 @@ export const clearExpandedPanel = ({ commit }) => {
export const fetchData = ({ dispatch }) => {
dispatch('fetchEnvironmentsData');
dispatch('fetchDashboard');
/**
* Annotations data is not yet fetched. This will be
* ready after the BE piece is implemented.
* https://gitlab.com/gitlab-org/gitlab/-/issues/211330
*/
if (isFeatureFlagEnabled('metricsDashboardAnnotations')) {
dispatch('fetchAnnotations');
}
dispatch('fetchAnnotations');
};
// Metrics dashboard
......
......@@ -9,7 +9,6 @@ class Projects::EnvironmentsController < Projects::ApplicationController
authorize_metrics_dashboard!
push_frontend_feature_flag(:prometheus_computed_alerts)
push_frontend_feature_flag(:metrics_dashboard_annotations, project)
end
before_action :authorize_read_environment!
before_action :authorize_create_environment!, only: [:new, :create]
......
......@@ -18,7 +18,6 @@ module Resolvers
def resolve(**args)
return [] unless dashboard
return [] unless Feature.enabled?(:metrics_dashboard_annotations, dashboard.environment&.project)
::Metrics::Dashboards::AnnotationsFinder.new(dashboard: dashboard, params: args).execute
end
......
......@@ -11,8 +11,7 @@ module Types
description: 'Path to a file with the dashboard definition'
field :annotations, Types::Metrics::Dashboards::AnnotationType.connection_type, null: true,
description: 'Annotations added to the dashboard. Will always return `null` ' \
'if `metrics_dashboard_annotations` feature flag is disabled',
description: 'Annotations added to the dashboard',
resolver: Resolvers::Metrics::Dashboards::AnnotationResolver
end
# rubocop: enable Graphql/AuthorizeTypes
......
---
title: Add metrics dashboard annotations feature, which enables marking interesting
events over metrics dashboard charts
merge_request: 30371
author:
type: added
......@@ -6027,7 +6027,7 @@ type Metadata {
type MetricsDashboard {
"""
Annotations added to the dashboard. Will always return `null` if `metrics_dashboard_annotations` feature flag is disabled
Annotations added to the dashboard
"""
annotations(
"""
......
......@@ -16917,7 +16917,7 @@
"fields": [
{
"name": "annotations",
"description": "Annotations added to the dashboard. Will always return `null` if `metrics_dashboard_annotations` feature flag is disabled",
"description": "Annotations added to the dashboard",
"args": [
{
"name": "from",
......
......@@ -28,8 +28,6 @@ module API
post ':id/metrics_dashboard/annotations' do
annotations_source_object = annotations_source[:class].find(params[:id])
not_found! unless Feature.enabled?(:metrics_dashboard_annotations, annotations_source_object.project)
forbidden! unless can?(current_user, :create_metrics_dashboard_annotation, annotations_source_object)
create_service_params = declared(params).merge(annotations_source[:create_service_param_key] => annotations_source_object)
......
......@@ -97,7 +97,11 @@ describe('Monitoring store actions', () => {
null,
state,
[],
[{ type: 'fetchEnvironmentsData' }, { type: 'fetchDashboard' }],
[
{ type: 'fetchEnvironmentsData' },
{ type: 'fetchDashboard' },
{ type: 'fetchAnnotations' },
],
);
});
......
......@@ -21,6 +21,7 @@ describe 'Getting Metrics Dashboard Annotations' do
create(:metrics_dashboard_annotation, environment: environment, starting_at: to.advance(minutes: 5), dashboard_path: path)
end
let(:args) { "from: \"#{from}\", to: \"#{to}\"" }
let(:fields) do
<<~QUERY
#{all_graphql_fields_for('MetricsDashboardAnnotation'.classify)}
......@@ -47,63 +48,40 @@ describe 'Getting Metrics Dashboard Annotations' do
)
end
context 'feature flag metrics_dashboard_annotations' do
let(:args) { "from: \"#{from}\", to: \"#{to}\"" }
before do
project.add_developer(current_user)
post_graphql(query, current_user: current_user)
end
before do
project.add_developer(current_user)
end
it_behaves_like 'a working graphql query'
context 'is off' do
before do
stub_feature_flags(metrics_dashboard_annotations: false)
post_graphql(query, current_user: current_user)
end
it 'returns annotations' do
annotations = graphql_data.dig('project', 'environments', 'nodes')[0].dig('metricsDashboard', 'annotations', 'nodes')
it 'returns empty nodes array' do
annotations = graphql_data.dig('project', 'environments', 'nodes')[0].dig('metricsDashboard', 'annotations', 'nodes')
expect(annotations).to match_array [{
"description" => annotation.description,
"id" => annotation.to_global_id.to_s,
"panelId" => annotation.panel_xid,
"startingAt" => annotation.starting_at.iso8601,
"endingAt" => nil
}]
end
expect(annotations).to be_empty
end
end
context 'arguments' do
context 'from is missing' do
let(:args) { "to: \"#{from}\"" }
context 'is on' do
before do
stub_feature_flags(metrics_dashboard_annotations: true)
it 'returns error' do
post_graphql(query, current_user: current_user)
end
it_behaves_like 'a working graphql query'
it 'returns annotations' do
annotations = graphql_data.dig('project', 'environments', 'nodes')[0].dig('metricsDashboard', 'annotations', 'nodes')
expect(annotations).to match_array [{
"description" => annotation.description,
"id" => annotation.to_global_id.to_s,
"panelId" => annotation.panel_xid,
"startingAt" => annotation.starting_at.iso8601,
"endingAt" => nil
}]
expect(graphql_errors[0]).to include("message" => "Field 'annotations' is missing required arguments: from")
end
end
context 'arguments' do
context 'from is missing' do
let(:args) { "to: \"#{from}\"" }
it 'returns error' do
post_graphql(query, current_user: current_user)
expect(graphql_errors[0]).to include("message" => "Field 'annotations' is missing required arguments: from")
end
end
context 'to is missing' do
let(:args) { "from: \"#{from}\"" }
context 'to is missing' do
let(:args) { "from: \"#{from}\"" }
it_behaves_like 'a working graphql query'
end
end
it_behaves_like 'a working graphql query'
end
end
end
......@@ -19,75 +19,55 @@ describe API::Metrics::Dashboard::Annotations do
end
context "with :source_type == #{source_type.pluralize}" do
context 'feature flag metrics_dashboard_annotations' do
context 'is on' do
before do
stub_feature_flags(metrics_dashboard_annotations: { enabled: true, thing: project })
end
context 'with correct permissions' do
context 'with valid parameters' do
it 'creates a new annotation', :aggregate_failures do
post api(url, user), params: params
context 'with correct permissions' do
context 'with valid parameters' do
it 'creates a new annotation', :aggregate_failures do
post api(url, user), params: params
expect(response).to have_gitlab_http_status(:created)
expect(json_response["#{source_type}_id"]).to eq(source.id)
expect(json_response['starting_at'].to_time).to eq(starting_at.to_time)
expect(json_response['ending_at'].to_time).to eq(ending_at.to_time)
expect(json_response['description']).to eq(params[:description])
expect(json_response['dashboard_path']).to eq(dashboard)
end
end
context 'with invalid parameters' do
it 'returns error messsage' do
post api(url, user), params: { dashboard_path: nil, starting_at: nil, description: nil }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to include({ "starting_at" => ["can't be blank"], "description" => ["can't be blank"], "dashboard_path" => ["can't be blank"] })
end
end
context 'with undeclared params' do
before do
params[:undeclared_param] = 'xyz'
end
it 'filters out undeclared params' do
expect(::Metrics::Dashboard::Annotations::CreateService).to receive(:new).with(user, hash_excluding(:undeclared_param))
post api(url, user), params: params
end
end
expect(response).to have_gitlab_http_status(:created)
expect(json_response["#{source_type}_id"]).to eq(source.id)
expect(json_response['starting_at'].to_time).to eq(starting_at.to_time)
expect(json_response['ending_at'].to_time).to eq(ending_at.to_time)
expect(json_response['description']).to eq(params[:description])
expect(json_response['dashboard_path']).to eq(dashboard)
end
end
context 'without correct permissions' do
let_it_be(:guest) { create(:user) }
before do
project.add_guest(guest)
end
it 'returns error messsage' do
post api(url, guest), params: params
context 'with invalid parameters' do
it 'returns error messsage' do
post api(url, user), params: { dashboard_path: nil, starting_at: nil, description: nil }
expect(response).to have_gitlab_http_status(:forbidden)
end
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to include({ "starting_at" => ["can't be blank"], "description" => ["can't be blank"], "dashboard_path" => ["can't be blank"] })
end
end
context 'is off' do
context 'with undeclared params' do
before do
stub_feature_flags(metrics_dashboard_annotations: { enabled: false })
params[:undeclared_param] = 'xyz'
end
it 'returns error messsage' do
post api(url, user), params: params
it 'filters out undeclared params' do
expect(::Metrics::Dashboard::Annotations::CreateService).to receive(:new).with(user, hash_excluding(:undeclared_param))
expect(response).to have_gitlab_http_status(:not_found)
post api(url, user), params: params
end
end
end
context 'without correct permissions' do
let_it_be(:guest) { create(:user) }
before do
project.add_guest(guest)
end
it 'returns error message' do
post api(url, guest), params: params
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
end
......
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