Commit bbaff070 authored by Mikolaj Wawrzyniak's avatar Mikolaj Wawrzyniak

Move cluster health dashboard to the core

In order to make clustr health dashbaord available to all users
we need to move #mertics_dashboard endpoint out of ee module
parent 0e405512
...@@ -10,6 +10,11 @@ class Admin::ClustersController < Clusters::ClustersController ...@@ -10,6 +10,11 @@ class Admin::ClustersController < Clusters::ClustersController
def clusterable def clusterable
@clusterable ||= InstanceClusterablePresenter.fabricate(Clusters::Instance.new, current_user: current_user) @clusterable ||= InstanceClusterablePresenter.fabricate(Clusters::Instance.new, current_user: current_user)
end end
end
Admin::ClustersController.prepend_if_ee('EE::Admin::ClustersController') def metrics_dashboard_params
{
cluster: cluster,
cluster_type: :admin
}
end
end
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
class Clusters::ClustersController < Clusters::BaseController class Clusters::ClustersController < Clusters::BaseController
include RoutableActions include RoutableActions
include Metrics::Dashboard::PrometheusApiProxy include Metrics::Dashboard::PrometheusApiProxy
include MetricsDashboard
before_action :cluster, only: [:cluster_status, :show, :update, :destroy, :clear_cache] before_action :cluster, only: [:cluster_status, :show, :update, :destroy, :clear_cache]
before_action :generate_gcp_authorize_url, only: [:new] before_action :generate_gcp_authorize_url, only: [:new]
......
...@@ -17,6 +17,12 @@ class Groups::ClustersController < Clusters::ClustersController ...@@ -17,6 +17,12 @@ class Groups::ClustersController < Clusters::ClustersController
def group def group
@group ||= find_routable!(Group, params[:group_id] || params[:id]) @group ||= find_routable!(Group, params[:group_id] || params[:id])
end end
end
Groups::ClustersController.prepend_if_ee('EE::Groups::ClustersController') def metrics_dashboard_params
{
cluster: cluster,
cluster_type: :group,
group: group
}
end
end
...@@ -23,6 +23,13 @@ class Projects::ClustersController < Clusters::ClustersController ...@@ -23,6 +23,13 @@ class Projects::ClustersController < Clusters::ClustersController
def repository def repository
@repository ||= project.repository @repository ||= project.repository
end end
end
Projects::ClustersController.prepend_if_ee('EE::Projects::ClustersController') def metrics_dashboard_params
params.permit(:embedded, :group, :title, :y_label).merge(
{
cluster: cluster,
cluster_type: :project
}
)
end
end
...@@ -344,6 +344,10 @@ module Clusters ...@@ -344,6 +344,10 @@ module Clusters
Feature.enabled?(:managed_apps_local_tiller, clusterable, default_enabled: true) Feature.enabled?(:managed_apps_local_tiller, clusterable, default_enabled: true)
end end
def prometheus_adapter
application_prometheus
end
private private
def unique_management_project_environment_scope def unique_management_project_environment_scope
......
...@@ -64,6 +64,10 @@ class ClusterablePresenter < Gitlab::View::Presenter::Delegated ...@@ -64,6 +64,10 @@ class ClusterablePresenter < Gitlab::View::Presenter::Delegated
raise NotImplementedError raise NotImplementedError
end end
def metrics_dashboard_path(cluster)
raise NotImplementedError
end
# Will be overridden in EE # Will be overridden in EE
def environments_cluster_path(cluster) def environments_cluster_path(cluster)
nil nil
......
...@@ -64,8 +64,27 @@ module Clusters ...@@ -64,8 +64,27 @@ module Clusters
!cluster.provided_by_user? !cluster.provided_by_user?
end end
def health_data(clusterable)
{
'clusters-path': clusterable.index_path,
'dashboard-endpoint': clusterable.metrics_dashboard_path(cluster),
'documentation-path': help_page_path('user/project/clusters/index', anchor: 'monitoring-your-kubernetes-cluster-ultimate'),
'empty-getting-started-svg-path': image_path('illustrations/monitoring/getting_started.svg'),
'empty-loading-svg-path': image_path('illustrations/monitoring/loading.svg'),
'empty-no-data-svg-path': image_path('illustrations/monitoring/no_data.svg'),
'empty-unable-to-connect-svg-path': image_path('illustrations/monitoring/unable_to_connect.svg'),
'settings-path': '',
'project-path': '',
'tags-path': ''
}
end
private private
def image_path(path)
ActionController::Base.helpers.image_path(path)
end
def clusterable def clusterable
if cluster.group_type? if cluster.group_type?
cluster.group cluster.group
......
...@@ -43,6 +43,10 @@ class GroupClusterablePresenter < ClusterablePresenter ...@@ -43,6 +43,10 @@ class GroupClusterablePresenter < ClusterablePresenter
def learn_more_link def learn_more_link
link_to(s_('ClusterIntegration|Learn more about group Kubernetes clusters'), help_page_path('user/group/clusters/index'), target: '_blank', rel: 'noopener noreferrer') link_to(s_('ClusterIntegration|Learn more about group Kubernetes clusters'), help_page_path('user/group/clusters/index'), target: '_blank', rel: 'noopener noreferrer')
end end
def metrics_dashboard_path(cluster)
metrics_dashboard_group_cluster_path(clusterable, cluster)
end
end end
GroupClusterablePresenter.prepend_if_ee('EE::GroupClusterablePresenter') GroupClusterablePresenter.prepend_if_ee('EE::GroupClusterablePresenter')
...@@ -81,6 +81,10 @@ class InstanceClusterablePresenter < ClusterablePresenter ...@@ -81,6 +81,10 @@ class InstanceClusterablePresenter < ClusterablePresenter
def learn_more_link def learn_more_link
link_to(s_('ClusterIntegration|Learn more about instance Kubernetes clusters'), help_page_path('user/instance/clusters/index'), target: '_blank', rel: 'noopener noreferrer') link_to(s_('ClusterIntegration|Learn more about instance Kubernetes clusters'), help_page_path('user/instance/clusters/index'), target: '_blank', rel: 'noopener noreferrer')
end end
def metrics_dashboard_path(cluster)
metrics_dashboard_admin_cluster_path(cluster)
end
end end
InstanceClusterablePresenter.prepend_if_ee('EE::InstanceClusterablePresenter') InstanceClusterablePresenter.prepend_if_ee('EE::InstanceClusterablePresenter')
...@@ -38,6 +38,10 @@ class ProjectClusterablePresenter < ClusterablePresenter ...@@ -38,6 +38,10 @@ class ProjectClusterablePresenter < ClusterablePresenter
def learn_more_link def learn_more_link
link_to(s_('ClusterIntegration|Learn more about Kubernetes'), help_page_path('user/project/clusters/index'), target: '_blank', rel: 'noopener noreferrer') link_to(s_('ClusterIntegration|Learn more about Kubernetes'), help_page_path('user/project/clusters/index'), target: '_blank', rel: 'noopener noreferrer')
end end
def metrics_dashboard_path(cluster)
metrics_dashboard_project_cluster_path(clusterable, cluster)
end
end end
ProjectClusterablePresenter.prepend_if_ee('EE::ProjectClusterablePresenter') ProjectClusterablePresenter.prepend_if_ee('EE::ProjectClusterablePresenter')
---
title: Open source cluster health dashboard and make it available to all users
merge_request: 35721
author:
type: changed
...@@ -190,7 +190,6 @@ Rails.application.routes.draw do ...@@ -190,7 +190,6 @@ Rails.application.routes.draw do
member do member do
Gitlab.ee do Gitlab.ee do
get :metrics, format: :json get :metrics, format: :json
get :metrics_dashboard
get :environments, format: :json get :environments, format: :json
end end
...@@ -200,6 +199,7 @@ Rails.application.routes.draw do ...@@ -200,6 +199,7 @@ Rails.application.routes.draw do
delete '/:application', to: 'clusters/applications#destroy', as: :uninstall_applications delete '/:application', to: 'clusters/applications#destroy', as: :uninstall_applications
end end
get :metrics_dashboard
get :'/prometheus/api/v1/*proxy_path', to: 'clusters#prometheus_proxy', as: :prometheus_api get :'/prometheus/api/v1/*proxy_path', to: 'clusters#prometheus_proxy', as: :prometheus_api
get :cluster_status, format: :json get :cluster_status, format: :json
delete :clear_cache delete :clear_cache
......
# frozen_string_literal: true
module EE
module Admin
module ClustersController
def metrics_dashboard_params
{
cluster: cluster,
cluster_type: :admin
}
end
end
end
end
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
module EE module EE
module Clusters module Clusters
module ClustersController module ClustersController
include MetricsDashboard
extend ActiveSupport::Concern extend ActiveSupport::Concern
prepended do prepended do
......
# frozen_string_literal: true
module EE
module Groups
module ClustersController
extend ActiveSupport::Concern
def metrics_dashboard_params
{
cluster: cluster,
cluster_type: :group,
group: group
}
end
end
end
end
# frozen_string_literal: true
module EE
module Projects
module ClustersController
def metrics_dashboard_params
params.permit(:embedded, :group, :title, :y_label).merge(
{
cluster: cluster,
cluster_type: :project
}
)
end
end
end
end
...@@ -8,10 +8,6 @@ module EE ...@@ -8,10 +8,6 @@ module EE
prepended do prepended do
include UsageStatistics include UsageStatistics
end end
def prometheus_adapter
application_prometheus
end
end end
end end
end end
...@@ -5,9 +5,5 @@ module EE ...@@ -5,9 +5,5 @@ module EE
def metrics_cluster_path(cluster, params = {}) def metrics_cluster_path(cluster, params = {})
raise NotImplementedError raise NotImplementedError
end end
def metrics_dashboard_path(cluster)
raise NotImplementedError
end
end end
end end
...@@ -3,30 +3,19 @@ ...@@ -3,30 +3,19 @@
module EE module EE
module Clusters module Clusters
module ClusterPresenter module ClusterPresenter
extend ::Gitlab::Utils::Override
override :health_data
def health_data(clusterable) def health_data(clusterable)
{ super.merge(
'clusters-path': clusterable.index_path,
'metrics-endpoint': clusterable.metrics_cluster_path(cluster, format: :json), 'metrics-endpoint': clusterable.metrics_cluster_path(cluster, format: :json),
'dashboard-endpoint': clusterable.metrics_dashboard_path(cluster),
'documentation-path': help_page_path('user/project/clusters/index', anchor: 'monitoring-your-kubernetes-cluster'),
'empty-getting-started-svg-path': image_path('illustrations/monitoring/getting_started.svg'),
'empty-loading-svg-path': image_path('illustrations/monitoring/loading.svg'),
'empty-no-data-svg-path': image_path('illustrations/monitoring/no_data.svg'),
'empty-unable-to-connect-svg-path': image_path('illustrations/monitoring/unable_to_connect.svg'),
'settings-path': '',
'project-path': '',
'tags-path': '',
'alerts-endpoint': alerts_endpoint, 'alerts-endpoint': alerts_endpoint,
'prometheus-alerts-available': prometheus_alerts_available 'prometheus-alerts-available': prometheus_alerts_available
} )
end end
private private
def image_path(path)
ActionController::Base.helpers.image_path(path)
end
def alerts_endpoint def alerts_endpoint
'/' if ::Feature.enabled?(:prometheus_computed_alerts) '/' if ::Feature.enabled?(:prometheus_computed_alerts)
end end
......
...@@ -16,11 +16,6 @@ module EE ...@@ -16,11 +16,6 @@ module EE
environments_group_cluster_path(clusterable, cluster) environments_group_cluster_path(clusterable, cluster)
end end
override :metrics_dashboard_path
def metrics_dashboard_path(cluster)
metrics_dashboard_group_cluster_path(clusterable, cluster)
end
private private
def can_read_cluster_environments? def can_read_cluster_environments?
......
...@@ -16,11 +16,6 @@ module EE ...@@ -16,11 +16,6 @@ module EE
environments_admin_cluster_path(cluster) environments_admin_cluster_path(cluster)
end end
override :metrics_dashboard_path
def metrics_dashboard_path(cluster)
metrics_dashboard_admin_cluster_path(cluster)
end
private private
def can_read_cluster_environments? def can_read_cluster_environments?
......
...@@ -8,10 +8,5 @@ module EE ...@@ -8,10 +8,5 @@ module EE
def metrics_cluster_path(cluster, params = {}) def metrics_cluster_path(cluster, params = {})
metrics_project_cluster_path(clusterable, cluster, params) metrics_project_cluster_path(clusterable, cluster, params)
end end
override :metrics_dashboard_path
def metrics_dashboard_path(cluster)
metrics_dashboard_project_cluster_path(clusterable, cluster)
end
end end
end end
...@@ -11,8 +11,7 @@ module EE ...@@ -11,8 +11,7 @@ module EE
override :permissions_by_route override :permissions_by_route
def permissions_by_route def permissions_by_route
super.concat([ super.concat([
ROUTE.new(::Gitlab::Metrics::Dashboard::Url.alert_regex, :read_prometheus_alerts), ROUTE.new(::Gitlab::Metrics::Dashboard::Url.alert_regex, :read_prometheus_alerts)
ROUTE.new(::Gitlab::Metrics::Dashboard::Url.clusters_regex, :read_cluster)
]) ])
end end
end end
......
...@@ -10,7 +10,6 @@ module EE ...@@ -10,7 +10,6 @@ module EE
def metrics_filters def metrics_filters
[ [
::Banzai::Filter::InlineAlertMetricsFilter, ::Banzai::Filter::InlineAlertMetricsFilter,
::Banzai::Filter::InlineClusterMetricsFilter,
*super *super
] ]
end end
......
...@@ -27,10 +27,6 @@ RSpec.describe Admin::ClustersController do ...@@ -27,10 +27,6 @@ RSpec.describe Admin::ClustersController do
before do before do
allow(::Clusters::Instance).to receive(:new).and_return(cluster.instance) allow(::Clusters::Instance).to receive(:new).and_return(cluster.instance)
end end
describe 'GET #metrics_dashboard' do
it_behaves_like 'the default dashboard'
end
end end
describe 'GET environments' do describe 'GET environments' do
......
...@@ -33,34 +33,6 @@ RSpec.describe Groups::ClustersController do ...@@ -33,34 +33,6 @@ RSpec.describe Groups::ClustersController do
clusterable.add_maintainer(user) clusterable.add_maintainer(user)
end end
context 'with inappropriate requests' do
context 'with anoymous user' do
before do
sign_out(user)
end
it 'renders not found' do
get :prometheus_proxy, params: prometheus_proxy_params
expect(response).to have_gitlab_http_status(:not_found)
end
context 'with invalid clusterable id' do
before do
sign_in(user)
end
let(:other_clusterable) { create(:group) }
it 'returns 404' do
get :prometheus_proxy, params: prometheus_proxy_params(id: other_clusterable.id)
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end
describe 'security' do describe 'security' do
let(:prometheus_adapter) { double(:prometheus_adapter, can_query?: true, query: nil) } let(:prometheus_adapter) { double(:prometheus_adapter, can_query?: true, query: nil) }
...@@ -78,28 +50,6 @@ RSpec.describe Groups::ClustersController do ...@@ -78,28 +50,6 @@ RSpec.describe Groups::ClustersController do
it { expect { go }.to be_denied_for(:user) } it { expect { go }.to be_denied_for(:user) }
it { expect { go }.to be_denied_for(:external) } it { expect { go }.to be_denied_for(:external) }
end end
describe 'GET #metrics_dashboard' do
let(:user) { create(:user) }
before do
clusterable.add_maintainer(user)
sign_in(user)
end
it_behaves_like 'the default dashboard'
end
end
private
def prometheus_proxy_params(params = {})
{
id: cluster.id.to_s,
group_id: group.name,
proxy_path: 'query',
query: '1'
}.merge(params)
end end
describe 'GET environments' do describe 'GET environments' do
......
...@@ -47,28 +47,5 @@ RSpec.describe Projects::ClustersController do ...@@ -47,28 +47,5 @@ RSpec.describe Projects::ClustersController do
it { expect { go }.to be_denied_for(:user) } it { expect { go }.to be_denied_for(:user) }
it { expect { go }.to be_denied_for(:external) } it { expect { go }.to be_denied_for(:external) }
end end
describe 'GET #metrics_dashboard' do
let(:user) { create(:user) }
before do
clusterable.add_maintainer(user)
sign_in(user)
end
it_behaves_like 'the default dashboard'
end
end
private
def prometheus_proxy_params(params = {})
{
id: cluster.id.to_s,
namespace_id: project.namespace.full_path,
project_id: project.name,
proxy_path: 'query',
query: '1'
}.merge(params)
end end
end end
...@@ -27,24 +27,4 @@ RSpec.describe Banzai::Filter::InlineMetricsRedactorFilter do ...@@ -27,24 +27,4 @@ RSpec.describe Banzai::Filter::InlineMetricsRedactorFilter do
it_behaves_like 'redacts the embed placeholder' it_behaves_like 'redacts the embed placeholder'
it_behaves_like 'retains the embed placeholder when applicable' it_behaves_like 'retains the embed placeholder when applicable'
end end
context 'for a cluster metric embed' do
let_it_be(:cluster) { create(:cluster, :provided_by_gcp, :project, projects: [project]) }
let(:params) { [project.namespace.path, project.path, cluster.id] }
let(:query_params) { { group: 'Cluster Health', title: 'CPU Usage', y_label: 'CPU (cores)' } }
let(:url) { urls.metrics_namespace_project_cluster_url(*params, **query_params) }
context 'with user who can read cluster' do
it_behaves_like 'redacts the embed placeholder'
it_behaves_like 'retains the embed placeholder when applicable'
end
context 'without user who can read cluster' do
let(:doc) { filter(input, current_user: create(:user)) }
it 'redacts the embed placeholder' do
expect(doc.to_s).to be_empty
end
end
end
end end
...@@ -17,18 +17,8 @@ RSpec.describe Clusters::ClusterPresenter do ...@@ -17,18 +17,8 @@ RSpec.describe Clusters::ClusterPresenter do
subject { cluster_presenter.health_data(clusterable_presenter) } subject { cluster_presenter.health_data(clusterable_presenter) }
it do it do
is_expected.to match( is_expected.to include(
'clusters-path': clusterable_presenter.index_path,
'metrics-endpoint': clusterable_presenter.metrics_cluster_path(cluster, format: :json), 'metrics-endpoint': clusterable_presenter.metrics_cluster_path(cluster, format: :json),
'dashboard-endpoint': clusterable_presenter.metrics_dashboard_path(cluster),
'documentation-path': help_page_path('user/project/clusters/index', anchor: 'monitoring-your-kubernetes-cluster'),
'empty-getting-started-svg-path': match_asset_path('/assets/illustrations/monitoring/getting_started.svg'),
'empty-loading-svg-path': match_asset_path('/assets/illustrations/monitoring/loading.svg'),
'empty-no-data-svg-path': match_asset_path('/assets/illustrations/monitoring/no_data.svg'),
'empty-unable-to-connect-svg-path': match_asset_path('/assets/illustrations/monitoring/unable_to_connect.svg'),
'settings-path': '',
'project-path': '',
'tags-path': '',
'alerts-endpoint': '/', 'alerts-endpoint': '/',
'prometheus-alerts-available': 'true' 'prometheus-alerts-available': 'true'
) )
......
...@@ -14,10 +14,4 @@ RSpec.describe InstanceClusterablePresenter do ...@@ -14,10 +14,4 @@ RSpec.describe InstanceClusterablePresenter do
it { is_expected.to eq(metrics_admin_cluster_path(cluster)) } it { is_expected.to eq(metrics_admin_cluster_path(cluster)) }
end end
describe '#metrics_dashboard_path' do
subject { presenter.metrics_dashboard_path(cluster) }
it { is_expected.to eq(metrics_dashboard_admin_cluster_path(cluster)) }
end
end end
...@@ -40,10 +40,4 @@ RSpec.describe GroupClusterablePresenter do ...@@ -40,10 +40,4 @@ RSpec.describe GroupClusterablePresenter do
it { is_expected.to be_nil } it { is_expected.to be_nil }
end end
end end
describe '#metrics_dashboard_path' do
subject { presenter.metrics_dashboard_path(cluster) }
it { is_expected.to eq(metrics_dashboard_group_cluster_path(group, cluster)) }
end
end end
...@@ -14,10 +14,4 @@ RSpec.describe ProjectClusterablePresenter do ...@@ -14,10 +14,4 @@ RSpec.describe ProjectClusterablePresenter do
it { is_expected.to eq(metrics_project_cluster_path(project, cluster)) } it { is_expected.to eq(metrics_project_cluster_path(project, cluster)) }
end end
describe '#metrics_dashboard_path' do
subject { presenter.metrics_dashboard_path(cluster) }
it { is_expected.to eq(metrics_dashboard_project_cluster_path(project, cluster)) }
end
end end
...@@ -74,21 +74,6 @@ RSpec.shared_examples 'cluster metrics' do ...@@ -74,21 +74,6 @@ RSpec.shared_examples 'cluster metrics' do
end end
end end
shared_examples 'the default dashboard' do
it 'returns a json object with the correct keys' do
get :metrics_dashboard, params: metrics_params, format: :json
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.keys).to contain_exactly('dashboard', 'status', 'metrics_data')
end
it 'is the default dashboard' do
get :metrics_dashboard, params: metrics_params, format: :json
expect(json_response['dashboard']['dashboard']).to eq('Cluster health')
end
end
private private
def go def go
......
...@@ -6,7 +6,6 @@ module Banzai ...@@ -6,7 +6,6 @@ module Banzai
def embed_params(node) def embed_params(node)
url = node['href'] url = node['href']
@query_params = query_params(url) @query_params = query_params(url)
return unless [:group, :title, :y_label].all? do |param| return unless [:group, :title, :y_label].all? do |param|
@query_params.include?(param) @query_params.include?(param)
end end
......
...@@ -77,6 +77,10 @@ module Banzai ...@@ -77,6 +77,10 @@ module Banzai
Route.new( Route.new(
::Gitlab::Metrics::Dashboard::Url.grafana_regex, ::Gitlab::Metrics::Dashboard::Url.grafana_regex,
:read_project :read_project
),
Route.new(
::Gitlab::Metrics::Dashboard::Url.clusters_regex,
:read_cluster
) )
] ]
end end
......
...@@ -48,7 +48,8 @@ module Banzai ...@@ -48,7 +48,8 @@ module Banzai
def self.metrics_filters def self.metrics_filters
[ [
Filter::InlineMetricsFilter, Filter::InlineMetricsFilter,
Filter::InlineGrafanaMetricsFilter Filter::InlineGrafanaMetricsFilter,
Filter::InlineClusterMetricsFilter
] ]
end end
......
...@@ -171,6 +171,16 @@ RSpec.describe Admin::ClustersController do ...@@ -171,6 +171,16 @@ RSpec.describe Admin::ClustersController do
end end
end end
it_behaves_like 'GET #metrics_dashboard for dashboard', 'Cluster health' do
let(:cluster) { create(:cluster, :instance, :provided_by_gcp) }
let(:metrics_dashboard_req_params) do
{
id: cluster.id
}
end
end
describe 'GET #prometheus_proxy' do describe 'GET #prometheus_proxy' do
let(:user) { admin } let(:user) { admin }
let(:proxyable) do let(:proxyable) do
......
...@@ -192,6 +192,17 @@ RSpec.describe Groups::ClustersController do ...@@ -192,6 +192,17 @@ RSpec.describe Groups::ClustersController do
end end
end end
it_behaves_like 'GET #metrics_dashboard for dashboard', 'Cluster health' do
let(:cluster) { create(:cluster, :provided_by_gcp, cluster_type: :group_type, groups: [group]) }
let(:metrics_dashboard_req_params) do
{
id: cluster.id,
group_id: group.name
}
end
end
describe 'GET #prometheus_proxy' do describe 'GET #prometheus_proxy' do
let(:proxyable) do let(:proxyable) do
create(:cluster, :provided_by_gcp, cluster_type: :group_type, groups: [group]) create(:cluster, :provided_by_gcp, cluster_type: :group_type, groups: [group])
......
...@@ -230,6 +230,18 @@ RSpec.describe Projects::ClustersController do ...@@ -230,6 +230,18 @@ RSpec.describe Projects::ClustersController do
end end
end end
it_behaves_like 'GET #metrics_dashboard for dashboard', 'Cluster health' do
let(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let(:metrics_dashboard_req_params) do
{
id: cluster.id,
namespace_id: project.namespace.full_path,
project_id: project.name
}
end
end
describe 'POST create for new cluster' do describe 'POST create for new cluster' do
let(:legacy_abac_param) { 'true' } let(:legacy_abac_param) { 'true' }
let(:params) do let(:params) do
......
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'Metrics rendering', :js, :use_clean_rails_memory_store_caching, :sidekiq_inline do RSpec.describe 'Metrics rendering', :js, :kubeclient, :use_clean_rails_memory_store_caching, :sidekiq_inline do
include PrometheusHelpers include PrometheusHelpers
include KubernetesHelpers
include GrafanaApiHelpers include GrafanaApiHelpers
include MetricsDashboardUrlHelpers include MetricsDashboardUrlHelpers
...@@ -166,6 +167,41 @@ RSpec.describe 'Metrics rendering', :js, :use_clean_rails_memory_store_caching, ...@@ -166,6 +167,41 @@ RSpec.describe 'Metrics rendering', :js, :use_clean_rails_memory_store_caching,
end end
end end
context 'for GitLab embedded cluster health metrics' do
before do
project.add_maintainer(user)
import_common_metrics
stub_any_prometheus_request_with_response
allow(Prometheus::ProxyService).to receive(:new).and_call_original
create(:clusters_applications_prometheus, :installed, cluster: cluster)
stub_kubeclient_discover(cluster.platform.api_url)
stub_prometheus_request(/prometheus-prometheus-server/, body: prometheus_values_body)
stub_prometheus_request(/prometheus\/api\/v1/, body: prometheus_values_body)
end
let_it_be(:cluster) { create(:cluster, :provided_by_gcp, :project, projects: [project], user: user) }
let(:params) { [project.namespace.path, project.path, cluster.id] }
let(:query_params) { { group: 'Cluster Health', title: 'CPU Usage', y_label: 'CPU (cores)' } }
let(:metrics_url) { urls.namespace_project_cluster_url(*params, **query_params) }
let(:description) { "# Summary \n[](#{metrics_url})" }
it 'shows embedded metrics' do
visit project_issue_path(project, issue)
expect(page).to have_css('div.prometheus-graph')
expect(page).to have_text(query_params[:title])
expect(page).to have_text(query_params[:y_label])
expect(page).not_to have_text(metrics_url)
expect(Prometheus::ProxyService)
.to have_received(:new)
.with(cluster, 'GET', 'query_range', hash_including('start', 'end', 'step'))
.at_least(:once)
end
end
def import_common_metrics def import_common_metrics
::Gitlab::DatabaseImporters::CommonMetrics::Importer.new.execute ::Gitlab::DatabaseImporters::CommonMetrics::Importer.new.execute
end end
......
...@@ -9,7 +9,7 @@ RSpec.describe Banzai::Filter::InlineClusterMetricsFilter do ...@@ -9,7 +9,7 @@ RSpec.describe Banzai::Filter::InlineClusterMetricsFilter do
let!(:project) { create(:project) } let!(:project) { create(:project) }
let(:params) { [project.namespace.path, project.path, cluster.id] } let(:params) { [project.namespace.path, project.path, cluster.id] }
let(:query_params) { { group: 'Food metrics', title: 'Pizza Consumption', y_label: 'Slice Count' } } let(:query_params) { { group: 'Food metrics', title: 'Pizza Consumption', y_label: 'Slice Count' } }
let(:trigger_url) { urls.metrics_namespace_project_cluster_url(*params, **query_params) } let(:trigger_url) { urls.namespace_project_cluster_url(*params, **query_params) }
let(:dashboard_url) do let(:dashboard_url) do
urls.metrics_dashboard_namespace_project_cluster_url( urls.metrics_dashboard_namespace_project_cluster_url(
*params, *params,
......
...@@ -29,6 +29,26 @@ RSpec.describe Banzai::Filter::InlineMetricsRedactorFilter do ...@@ -29,6 +29,26 @@ RSpec.describe Banzai::Filter::InlineMetricsRedactorFilter do
it_behaves_like 'retains the embed placeholder when applicable' it_behaves_like 'retains the embed placeholder when applicable'
end end
context 'for a cluster metric embed' do
let_it_be(:cluster) { create(:cluster, :provided_by_gcp, :project, projects: [project]) }
let(:params) { [project.namespace.path, project.path, cluster.id] }
let(:query_params) { { group: 'Cluster Health', title: 'CPU Usage', y_label: 'CPU (cores)' } }
let(:url) { urls.metrics_dashboard_namespace_project_cluster_url(*params, **query_params) }
context 'with user who can read cluster' do
it_behaves_like 'redacts the embed placeholder'
it_behaves_like 'retains the embed placeholder when applicable'
end
context 'without user who can read cluster' do
let(:doc) { filter(input, current_user: create(:user)) }
it 'redacts the embed placeholder' do
expect(doc.to_s).to be_empty
end
end
end
context 'the user has requisite permissions' do context 'the user has requisite permissions' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:doc) { filter(input, current_user: user) } let(:doc) { filter(input, current_user: user) }
......
...@@ -249,4 +249,44 @@ RSpec.describe Clusters::ClusterPresenter do ...@@ -249,4 +249,44 @@ RSpec.describe Clusters::ClusterPresenter do
it { is_expected.to be_truthy } it { is_expected.to be_truthy }
end end
end end
describe '#health_data' do
shared_examples 'cluster health data' do
let(:user) { create(:user) }
let(:cluster_presenter) { cluster.present(current_user: user) }
let(:clusterable_presenter) do
ClusterablePresenter.fabricate(clusterable, current_user: user)
end
subject { cluster_presenter.health_data(clusterable_presenter) }
it do
is_expected.to include('clusters-path': clusterable_presenter.index_path,
'dashboard-endpoint': clusterable_presenter.metrics_dashboard_path(cluster),
'documentation-path': help_page_path('user/project/clusters/index', anchor: 'monitoring-your-kubernetes-cluster-ultimate'),
'empty-getting-started-svg-path': match_asset_path('/assets/illustrations/monitoring/getting_started.svg'),
'empty-loading-svg-path': match_asset_path('/assets/illustrations/monitoring/loading.svg'),
'empty-no-data-svg-path': match_asset_path('/assets/illustrations/monitoring/no_data.svg'),
'empty-unable-to-connect-svg-path': match_asset_path('/assets/illustrations/monitoring/unable_to_connect.svg'),
'settings-path': '',
'project-path': '',
'tags-path': '')
end
end
context 'with project cluster' do
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
let(:clusterable) { cluster.project }
it_behaves_like 'cluster health data'
end
context 'with group cluster' do
let(:cluster) { create(:cluster, :group, :provided_by_gcp) }
let(:clusterable) { cluster.group }
it_behaves_like 'cluster health data'
end
end
end end
...@@ -94,4 +94,10 @@ RSpec.describe GroupClusterablePresenter do ...@@ -94,4 +94,10 @@ RSpec.describe GroupClusterablePresenter do
it { is_expected.to eq(group_cluster_path(group, cluster)) } it { is_expected.to eq(group_cluster_path(group, cluster)) }
end end
describe '#metrics_dashboard_path' do
subject { presenter.metrics_dashboard_path(cluster) }
it { is_expected.to eq(metrics_dashboard_group_cluster_path(group, cluster)) }
end
end end
...@@ -26,4 +26,10 @@ RSpec.describe InstanceClusterablePresenter do ...@@ -26,4 +26,10 @@ RSpec.describe InstanceClusterablePresenter do
it { is_expected.to eq(clear_cache_admin_cluster_path(cluster)) } it { is_expected.to eq(clear_cache_admin_cluster_path(cluster)) }
end end
describe '#metrics_dashboard_path' do
subject { presenter.metrics_dashboard_path(cluster) }
it { is_expected.to eq(metrics_dashboard_admin_cluster_path(cluster)) }
end
end end
...@@ -94,4 +94,10 @@ RSpec.describe ProjectClusterablePresenter do ...@@ -94,4 +94,10 @@ RSpec.describe ProjectClusterablePresenter do
it { is_expected.to eq(project_cluster_path(project, cluster)) } it { is_expected.to eq(project_cluster_path(project, cluster)) }
end end
describe '#metrics_dashboard_path' do
subject { presenter.metrics_dashboard_path(cluster) }
it { is_expected.to eq(metrics_dashboard_project_cluster_path(project, cluster)) }
end
end end
...@@ -4,7 +4,8 @@ RSpec.shared_examples_for 'GET #metrics_dashboard correctly formatted response' ...@@ -4,7 +4,8 @@ RSpec.shared_examples_for 'GET #metrics_dashboard correctly formatted response'
it 'returns a json object with the correct keys' do it 'returns a json object with the correct keys' do
get :metrics_dashboard, params: metrics_dashboard_req_params, format: :json get :metrics_dashboard, params: metrics_dashboard_req_params, format: :json
# Exlcude `all_dashboards` to handle separately. # Exclude `all_dashboards` to handle separately, at spec/controllers/projects/environments_controller_spec.rb:565
# because `all_dashboards` key is not part of expected shared behavior
found_keys = json_response.keys - ['all_dashboards'] found_keys = json_response.keys - ['all_dashboards']
expect(response).to have_gitlab_http_status(status_code) expect(response).to have_gitlab_http_status(status_code)
......
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