summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Trzcinski <ayufan@ayufan.eu>2017-05-23 17:16:46 +0200
committerKamil Trzcinski <ayufan@ayufan.eu>2017-05-23 17:20:26 +0200
commit869aad7a8b12cc85b984f90906475e516c075385 (patch)
tree888b46340f9113d8fe4856f070a83b5af8df4baf
parent35ab669a957dd63a5c662ba909f368380e3a60c7 (diff)
downloadgitlab-ce-connect-to-prometheus-via-kubernetes.tar.gz
Connect via Kubernetes to Prometheus running in Kubernetes clusterconnect-to-prometheus-via-kubernetes
-rw-r--r--app/controllers/concerns/service_params.rb3
-rw-r--r--app/models/project_services/kubernetes_service.rb8
-rw-r--r--app/models/project_services/prometheus_service.rb18
-rw-r--r--lib/gitlab/prometheus_client.rb36
4 files changed, 43 insertions, 22 deletions
diff --git a/app/controllers/concerns/service_params.rb b/app/controllers/concerns/service_params.rb
index be2e6c7f193..ef6fde197f0 100644
--- a/app/controllers/concerns/service_params.rb
+++ b/app/controllers/concerns/service_params.rb
@@ -59,7 +59,8 @@ module ServiceParams
:url,
:user_key,
:username,
- :webhook
+ :webhook,
+ :use_kubernetes
].freeze
# Parameters to ignore if no value is specified
diff --git a/app/models/project_services/kubernetes_service.rb b/app/models/project_services/kubernetes_service.rb
index b2494a0be6e..67c73f63e95 100644
--- a/app/models/project_services/kubernetes_service.rb
+++ b/app/models/project_services/kubernetes_service.rb
@@ -134,6 +134,14 @@ class KubernetesService < DeploymentService
{ pods: pods }
end
+ def rest_client_for(kind, name, port, namespace = '')
+ kube_client = build_kubeclient!
+ rest_client = kube_client.rest_client
+ base_url = rest_client.url
+ proxy_url = kube_client.proxy_url(kind, name, port, namespace)
+ [rest_client[proxy_url.sub(base_url, '')], kube_client.headers]
+ end
+
TEMPLATE_PLACEHOLDER = 'Kubernetes namespace'.freeze
private
diff --git a/app/models/project_services/prometheus_service.rb b/app/models/project_services/prometheus_service.rb
index ec72cb6856d..74d9e36542b 100644
--- a/app/models/project_services/prometheus_service.rb
+++ b/app/models/project_services/prometheus_service.rb
@@ -7,9 +7,10 @@ class PrometheusService < MonitoringService
# Access to prometheus is directly through the API
prop_accessor :api_url
+ boolean_accessor :use_kubernetes
with_options presence: true, if: :activated? do
- validates :api_url, url: true
+ validates :api_url, url: true, unless: :use_kubernetes?
end
after_save :clear_reactive_cache!
@@ -46,6 +47,11 @@ class PrometheusService < MonitoringService
def fields
[
{
+ type: 'checkbox',
+ name: 'use_kubernetes',
+ title: 'Use Kubernetes Service'
+ },
+ {
type: 'text',
name: 'api_url',
title: 'API URL',
@@ -88,6 +94,14 @@ class PrometheusService < MonitoringService
end
def client
- @prometheus ||= Gitlab::PrometheusClient.new(api_url: api_url)
+ rest_client, headers = kubernetes_prometheus
+
+ @prometheus ||= Gitlab::PrometheusClient.new(api_url: api_url, rest_client: rest_client, headers: headers)
+ end
+
+ def kubernetes_prometheus
+ return unless use_kubernetes?
+
+ project.kubernetes_service&.rest_client_for('service', 'prometheus', 9090, 'prometheus')
end
end
diff --git a/lib/gitlab/prometheus_client.rb b/lib/gitlab/prometheus_client.rb
index 5b51a1779dd..22f744373ce 100644
--- a/lib/gitlab/prometheus_client.rb
+++ b/lib/gitlab/prometheus_client.rb
@@ -3,10 +3,12 @@ module Gitlab
# Helper methods to interact with Prometheus network services & resources
class PrometheusClient
- attr_reader :api_url
+ attr_reader :api_url, :rest_client, :headers
- def initialize(api_url:)
+ def initialize(api_url:, rest_client: nil, headers: nil)
@api_url = api_url
+ @rest_client = rest_client || RestClient::Resource.new(api_url)
+ @headers = headers || {}
end
def ping
@@ -32,24 +34,15 @@ module Gitlab
private
def json_api_get(type, args = {})
- get(join_api_url(type, args))
+ path = ['api', 'v1', type].join('/')
+ get(path, args)
rescue Errno::ECONNREFUSED
raise PrometheusError, 'Connection refused'
end
- def join_api_url(type, args = {})
- url = URI.parse(api_url)
- rescue URI::Error
- raise PrometheusError, "Invalid API URL: #{api_url}"
- else
- url.path = [url.path.sub(%r{/+\z}, ''), 'api', 'v1', type].join('/')
- url.query = args.to_query
-
- url.to_s
- end
-
- def get(url)
- handle_response(HTTParty.get(url))
+ def get(path, args)
+ response = rest_client[path].get(headers.merge(params: args))
+ handle_response(response)
rescue SocketError
raise PrometheusError, "Can't connect to #{url}"
rescue OpenSSL::SSL::SSLError
@@ -59,15 +52,20 @@ module Gitlab
end
def handle_response(response)
- if response.code == 200 && response['status'] == 'success'
- response['data'] || {}
+ json_data = json_response(response)
+ if response.code == 200 && json_data['status'] == 'success'
+ json_data['data'] || {}
elsif response.code == 400
- raise PrometheusError, response['error'] || 'Bad data received'
+ raise PrometheusError, json_data['error'] || 'Bad data received'
else
raise PrometheusError, "#{response.code} - #{response.body}"
end
end
+ def json_response(response)
+ JSON.parse(response.body)
+ end
+
def get_result(expected_type)
data = yield
data['result'] if data['resultType'] == expected_type