Backports relevant changes made in https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/5163 to CE
This commit is contained in:
parent
4063141223
commit
eb7c08c7a6
|
|
@ -4,4 +4,23 @@ module EnvironmentsHelper
|
|||
endpoint: project_environments_path(@project, format: :json)
|
||||
}
|
||||
end
|
||||
|
||||
def metrics_data(project, environment)
|
||||
{
|
||||
"settings-path" => edit_project_service_path(project, 'prometheus'),
|
||||
"clusters-path" => project_clusters_path(project),
|
||||
"current-environment-name": environment.name,
|
||||
"documentation-path" => help_page_path('administration/monitoring/prometheus/index.md'),
|
||||
"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'),
|
||||
"metrics-endpoint" => additional_metrics_project_environment_path(project, environment, format: :json),
|
||||
"deployment-endpoint" => project_environment_deployments_path(project, environment, format: :json),
|
||||
"environments-endpoint": project_environments_path(project, format: :json),
|
||||
"project-path" => project_path(project),
|
||||
"tags-path" => project_tags_path(project),
|
||||
"has-metrics" => "#{environment.has_metrics?}"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,6 +21,14 @@ module Clusters
|
|||
end
|
||||
end
|
||||
|
||||
def ready_status
|
||||
[:installed]
|
||||
end
|
||||
|
||||
def ready?
|
||||
ready_status.include?(status_name)
|
||||
end
|
||||
|
||||
def chart
|
||||
'stable/prometheus'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -24,11 +24,10 @@ module PrometheusAdapter
|
|||
def query(query_name, *args)
|
||||
return unless can_query?
|
||||
|
||||
query_class = Gitlab::Prometheus::Queries.const_get("#{query_name.to_s.classify}Query")
|
||||
query_class = query_klass_for(query_name)
|
||||
query_args = build_query_args(*args)
|
||||
|
||||
args.map!(&:id)
|
||||
|
||||
with_reactive_cache(query_class.name, *args, &query_class.method(:transform_reactive_result))
|
||||
with_reactive_cache(query_class.name, *query_args, &query_class.method(:transform_reactive_result))
|
||||
end
|
||||
|
||||
# Cache metrics for specific environment
|
||||
|
|
@ -44,5 +43,13 @@ module PrometheusAdapter
|
|||
rescue Gitlab::PrometheusClient::Error => err
|
||||
{ success: false, result: err.message }
|
||||
end
|
||||
|
||||
def query_klass_for(query_name)
|
||||
Gitlab::Prometheus::Queries.const_get("#{query_name.to_s.classify}Query")
|
||||
end
|
||||
|
||||
def build_query_args(*args)
|
||||
args.map(&:id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class InternalId < ActiveRecord::Base
|
|||
belongs_to :project
|
||||
belongs_to :namespace
|
||||
|
||||
enum usage: { issues: 0, merge_requests: 1, deployments: 2, milestones: 3, epics: 4, ci_pipelines: 5 }
|
||||
enum usage: { issues: 0, merge_requests: 1, deployments: 2, milestones: 3, epics: 4, ci_pipelines: 5, prometheus_alerts: 6 }
|
||||
|
||||
validates :usage, presence: true
|
||||
|
||||
|
|
|
|||
|
|
@ -50,17 +50,17 @@ module Clusters
|
|||
end
|
||||
|
||||
def remove_installation_pod
|
||||
helm_api.delete_installation_pod!(install_command.pod_name)
|
||||
helm_api.delete_pod!(install_command.pod_name)
|
||||
rescue
|
||||
# no-op
|
||||
end
|
||||
|
||||
def installation_phase
|
||||
helm_api.installation_status(install_command.pod_name)
|
||||
helm_api.status(install_command.pod_name)
|
||||
end
|
||||
|
||||
def installation_errors
|
||||
helm_api.installation_log(install_command.pod_name)
|
||||
helm_api.log(install_command.pod_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ module Prometheus
|
|||
return unless deployment_platform.respond_to?(:cluster)
|
||||
|
||||
cluster = deployment_platform.cluster
|
||||
return unless cluster.application_prometheus&.installed?
|
||||
return unless cluster.application_prometheus&.ready?
|
||||
|
||||
cluster.application_prometheus
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,17 +2,11 @@
|
|||
- page_title "Metrics for environment", @environment.name
|
||||
|
||||
.prometheus-container{ class: container_class }
|
||||
#prometheus-graphs{ data: { "settings-path": edit_project_service_path(@project, 'prometheus'),
|
||||
"clusters-path": project_clusters_path(@project),
|
||||
"current-environment-name": @environment.name,
|
||||
"documentation-path": help_page_path('administration/monitoring/prometheus/index.md'),
|
||||
"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'),
|
||||
"metrics-endpoint": additional_metrics_project_environment_path(@project, @environment, format: :json),
|
||||
"deployment-endpoint": project_environment_deployments_path(@project, @environment, format: :json),
|
||||
"environments-endpoint": project_environments_path(@project, format: :json),
|
||||
"project-path": project_path(@project),
|
||||
"tags-path": project_tags_path(@project),
|
||||
"has-metrics": "#{@environment.has_metrics?}" } }
|
||||
.top-area
|
||||
.row
|
||||
.col-sm-6
|
||||
%h3
|
||||
Environment:
|
||||
= link_to @environment.name, environment_path(@environment)
|
||||
|
||||
#prometheus-graphs{ data: metrics_data(@project, @environment) }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
module Gitlab
|
||||
module Kubernetes
|
||||
class ConfigMap
|
||||
def initialize(name, values)
|
||||
def initialize(name, values = "")
|
||||
@name = name
|
||||
@values = values
|
||||
end
|
||||
|
|
@ -13,6 +13,10 @@ module Gitlab
|
|||
resource
|
||||
end
|
||||
|
||||
def config_map_name
|
||||
"values-content-configuration-#{name}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :name, :values
|
||||
|
|
@ -25,10 +29,6 @@ module Gitlab
|
|||
}
|
||||
end
|
||||
|
||||
def config_map_name
|
||||
"values-content-configuration-#{name}"
|
||||
end
|
||||
|
||||
def namespace
|
||||
Gitlab::Kubernetes::Helm::NAMESPACE
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,15 +2,17 @@ module Gitlab
|
|||
module Kubernetes
|
||||
module Helm
|
||||
class Api
|
||||
attr_reader :kubeclient, :namespace
|
||||
|
||||
def initialize(kubeclient)
|
||||
@kubeclient = kubeclient
|
||||
@namespace = Gitlab::Kubernetes::Namespace.new(Gitlab::Kubernetes::Helm::NAMESPACE, kubeclient)
|
||||
end
|
||||
|
||||
def install(command)
|
||||
@namespace.ensure_exists!
|
||||
namespace.ensure_exists!
|
||||
create_config_map(command) if command.config_map?
|
||||
@kubeclient.create_pod(command.pod_resource)
|
||||
kubeclient.create_pod(command.pod_resource)
|
||||
end
|
||||
|
||||
##
|
||||
|
|
@ -20,23 +22,23 @@ module Gitlab
|
|||
#
|
||||
# values: "Pending", "Running", "Succeeded", "Failed", "Unknown"
|
||||
#
|
||||
def installation_status(pod_name)
|
||||
@kubeclient.get_pod(pod_name, @namespace.name).status.phase
|
||||
def status(pod_name)
|
||||
kubeclient.get_pod(pod_name, namespace.name).status.phase
|
||||
end
|
||||
|
||||
def installation_log(pod_name)
|
||||
@kubeclient.get_pod_log(pod_name, @namespace.name).body
|
||||
def log(pod_name)
|
||||
kubeclient.get_pod_log(pod_name, namespace.name).body
|
||||
end
|
||||
|
||||
def delete_installation_pod!(pod_name)
|
||||
@kubeclient.delete_pod(pod_name, @namespace.name)
|
||||
def delete_pod!(pod_name)
|
||||
kubeclient.delete_pod(pod_name, namespace.name)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_config_map(command)
|
||||
command.config_map_resource.tap do |config_map_resource|
|
||||
@kubeclient.create_config_map(config_map_resource)
|
||||
kubeclient.create_config_map(config_map_resource)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ module Gitlab
|
|||
Deployment.find_by(id: deployment_id).try do |deployment|
|
||||
query_metrics(
|
||||
deployment.project,
|
||||
deployment.environment,
|
||||
common_query_context(
|
||||
deployment.environment,
|
||||
timeframe_start: (deployment.created_at - 30.minutes).to_f,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ module Gitlab
|
|||
::Environment.find_by(id: environment_id).try do |environment|
|
||||
query_metrics(
|
||||
environment.project,
|
||||
environment,
|
||||
common_query_context(environment, timeframe_start: 8.hours.ago.to_f, timeframe_end: Time.now.to_f)
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ module Gitlab
|
|||
module Prometheus
|
||||
module Queries
|
||||
module QueryAdditionalMetrics
|
||||
def query_metrics(project, query_context)
|
||||
def query_metrics(project, environment, query_context)
|
||||
matched_metrics(project).map(&query_group(query_context))
|
||||
.select(&method(:group_with_any_metrics))
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,4 +22,10 @@ describe Gitlab::Kubernetes::ConfigMap do
|
|||
is_expected.to eq(resource)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#config_map_name' do
|
||||
it 'returns the config_map name' do
|
||||
expect(config_map.config_map_name).to eq("values-content-configuration-#{application.name}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -49,33 +49,33 @@ describe Gitlab::Kubernetes::Helm::Api do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#installation_status' do
|
||||
describe '#status' do
|
||||
let(:phase) { Gitlab::Kubernetes::Pod::RUNNING }
|
||||
let(:pod) { Kubeclient::Resource.new(status: { phase: phase }) } # partial representation
|
||||
|
||||
it 'fetches POD phase from kubernetes cluster' do
|
||||
expect(client).to receive(:get_pod).with(command.pod_name, gitlab_namespace).once.and_return(pod)
|
||||
|
||||
expect(subject.installation_status(command.pod_name)).to eq(phase)
|
||||
expect(subject.status(command.pod_name)).to eq(phase)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#installation_log' do
|
||||
describe '#log' do
|
||||
let(:log) { 'some output' }
|
||||
let(:response) { RestClient::Response.new(log) }
|
||||
|
||||
it 'fetches POD phase from kubernetes cluster' do
|
||||
expect(client).to receive(:get_pod_log).with(command.pod_name, gitlab_namespace).once.and_return(response)
|
||||
|
||||
expect(subject.installation_log(command.pod_name)).to eq(log)
|
||||
expect(subject.log(command.pod_name)).to eq(log)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#delete_installation_pod!' do
|
||||
describe '#delete_pod!' do
|
||||
it 'deletes the POD from kubernetes cluster' do
|
||||
expect(client).to receive(:delete_pod).with(command.pod_name, gitlab_namespace).once
|
||||
|
||||
subject.delete_installation_pod!(command.pod_name)
|
||||
subject.delete_pod!(command.pod_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -34,6 +34,47 @@ describe Clusters::Applications::Prometheus do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#ready' do
|
||||
let(:project) { create(:project) }
|
||||
let(:cluster) { create(:cluster, projects: [project]) }
|
||||
|
||||
it 'returns true when installed' do
|
||||
application = build(:clusters_applications_prometheus, :installed, cluster: cluster)
|
||||
|
||||
expect(application.ready?).to be true
|
||||
end
|
||||
|
||||
it 'returns false when not_installable' do
|
||||
application = build(:clusters_applications_prometheus, :not_installable, cluster: cluster)
|
||||
|
||||
expect(application.ready?).to be false
|
||||
end
|
||||
|
||||
it 'returns false when installable' do
|
||||
application = build(:clusters_applications_prometheus, :installable, cluster: cluster)
|
||||
|
||||
expect(application.ready?).to be false
|
||||
end
|
||||
|
||||
it 'returns false when scheduled' do
|
||||
application = build(:clusters_applications_prometheus, :scheduled, cluster: cluster)
|
||||
|
||||
expect(application.ready?).to be false
|
||||
end
|
||||
|
||||
it 'returns false when installing' do
|
||||
application = build(:clusters_applications_prometheus, :installing, cluster: cluster)
|
||||
|
||||
expect(application.ready?).to be false
|
||||
end
|
||||
|
||||
it 'returns false when errored' do
|
||||
application = build(:clusters_applications_prometheus, :errored, cluster: cluster)
|
||||
|
||||
expect(application.ready?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
describe '#prometheus_client' do
|
||||
context 'cluster is nil' do
|
||||
it 'returns nil' do
|
||||
|
|
@ -102,15 +143,17 @@ describe Clusters::Applications::Prometheus do
|
|||
let(:kubeclient) { double('kubernetes client') }
|
||||
let(:prometheus) { create(:clusters_applications_prometheus) }
|
||||
|
||||
subject { prometheus.install_command }
|
||||
|
||||
it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) }
|
||||
it 'returns an instance of Gitlab::Kubernetes::Helm::InstallCommand' do
|
||||
expect(prometheus.install_command).to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand)
|
||||
end
|
||||
|
||||
it 'should be initialized with 3 arguments' do
|
||||
expect(subject.name).to eq('prometheus')
|
||||
expect(subject.chart).to eq('stable/prometheus')
|
||||
expect(subject.version).to eq('6.7.3')
|
||||
expect(subject.values).to eq(prometheus.values)
|
||||
command = prometheus.install_command
|
||||
|
||||
expect(command.name).to eq('prometheus')
|
||||
expect(command.chart).to eq('stable/prometheus')
|
||||
expect(command.version).to eq('6.7.3')
|
||||
expect(command.values).to eq(prometheus.values)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ RSpec.shared_examples 'additional metrics query' do
|
|||
|
||||
shared_examples 'query context containing environment slug and filter' do
|
||||
it 'contains ci_environment_slug' do
|
||||
expect(subject).to receive(:query_metrics).with(project, hash_including(ci_environment_slug: environment.slug))
|
||||
expect(subject).to receive(:query_metrics).with(project, environment, hash_including(ci_environment_slug: environment.slug))
|
||||
|
||||
subject.query(*query_params)
|
||||
end
|
||||
|
|
@ -33,6 +33,7 @@ RSpec.shared_examples 'additional metrics query' do
|
|||
it 'contains environment filter' do
|
||||
expect(subject).to receive(:query_metrics).with(
|
||||
project,
|
||||
environment,
|
||||
hash_including(
|
||||
environment_filter: "container_name!=\"POD\",environment=\"#{environment.slug}\""
|
||||
)
|
||||
|
|
@ -50,7 +51,7 @@ RSpec.shared_examples 'additional metrics query' do
|
|||
it_behaves_like 'query context containing environment slug and filter'
|
||||
|
||||
it 'query context contains kube_namespace' do
|
||||
expect(subject).to receive(:query_metrics).with(project, hash_including(kube_namespace: kube_namespace))
|
||||
expect(subject).to receive(:query_metrics).with(project, environment, hash_including(kube_namespace: kube_namespace))
|
||||
|
||||
subject.query(*query_params)
|
||||
end
|
||||
|
|
@ -74,7 +75,7 @@ RSpec.shared_examples 'additional metrics query' do
|
|||
it_behaves_like 'query context containing environment slug and filter'
|
||||
|
||||
it 'query context contains empty kube_namespace' do
|
||||
expect(subject).to receive(:query_metrics).with(project, hash_including(kube_namespace: ''))
|
||||
expect(subject).to receive(:query_metrics).with(project, environment, hash_including(kube_namespace: ''))
|
||||
|
||||
subject.query(*query_params)
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue