diff options
author | Kamil Trzcinski <ayufan@ayufan.eu> | 2017-05-23 17:16:46 +0200 |
---|---|---|
committer | Kamil Trzcinski <ayufan@ayufan.eu> | 2017-05-23 17:20:26 +0200 |
commit | 869aad7a8b12cc85b984f90906475e516c075385 (patch) | |
tree | 888b46340f9113d8fe4856f070a83b5af8df4baf | |
parent | 35ab669a957dd63a5c662ba909f368380e3a60c7 (diff) | |
download | gitlab-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.rb | 3 | ||||
-rw-r--r-- | app/models/project_services/kubernetes_service.rb | 8 | ||||
-rw-r--r-- | app/models/project_services/prometheus_service.rb | 18 | ||||
-rw-r--r-- | lib/gitlab/prometheus_client.rb | 36 |
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 |