Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-09-12 00:08:44 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-09-12 00:08:44 +0300
commita66475b6beb46d77b9ff3fe30453be2d52779048 (patch)
tree39fd943e67dd66b1d734028f5449d8a41c4fe58f /lib/gitlab/consul
parent48e26d30fd251f87a2e136d8997ef2ec35859e71 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/consul')
-rw-r--r--lib/gitlab/consul/internal.rb85
1 files changed, 85 insertions, 0 deletions
diff --git a/lib/gitlab/consul/internal.rb b/lib/gitlab/consul/internal.rb
new file mode 100644
index 00000000000..8d99ea9f3c0
--- /dev/null
+++ b/lib/gitlab/consul/internal.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Consul
+ class Internal
+ Error = Class.new(StandardError)
+ UnexpectedResponseError = Class.new(Gitlab::Consul::Internal::Error)
+ SocketError = Class.new(Gitlab::Consul::Internal::Error)
+ SSLError = Class.new(Gitlab::Consul::Internal::Error)
+ ECONNREFUSED = Class.new(Gitlab::Consul::Internal::Error)
+
+ class << self
+ def api_url
+ Gitlab.config.consul.api_url.to_s.presence if Gitlab.config.consul
+ rescue Settingslogic::MissingSetting
+ Gitlab::AppLogger.error('Consul api_url is not present in config/gitlab.yml')
+
+ nil
+ end
+
+ def discover_service(service_name:)
+ return unless service_name.present? && api_url
+
+ api_path = URI.join(api_url, '/v1/catalog/service/', URI.encode_www_form_component(service_name)).to_s
+ services = json_get(api_path, allow_local_requests: true, open_timeout: 5, read_timeout: 10)
+
+ # Use the first service definition
+ service = services&.first
+
+ return unless service
+
+ service_address = service['ServiceAddress'] || service['Address']
+ service_port = service['ServicePort']
+
+ [service_address, service_port]
+ end
+
+ def discover_prometheus_uri
+ service_address, service_port = discover_service(service_name: 'prometheus')
+
+ return unless service_address && service_port
+
+ # There really is not a way to discover whether a Prometheus connection is using TLS or not
+ # Try TLS first because HTTPS will return fast if failed.
+ %w[https http].find do |scheme|
+ connection_url = "#{scheme}://#{service_address}:#{service_port}"
+ break connection_url if Gitlab::PrometheusClient.new(connection_url, allow_local_requests: true).healthy?
+ rescue
+ nil
+ end
+ end
+
+ private
+
+ def json_get(path, options)
+ response = get(path, options)
+ code = response.try(:code)
+ body = response.try(:body)
+
+ raise Consul::Internal::UnexpectedResponseError unless code == 200 && body
+
+ parse_response_body(body)
+ end
+
+ def parse_response_body(body)
+ Gitlab::Json.parse(body)
+ rescue
+ raise Consul::Internal::UnexpectedResponseError
+ end
+
+ def get(path, options)
+ Gitlab::HTTP.get(path, options)
+ rescue ::SocketError
+ raise Consul::Internal::SocketError
+ rescue OpenSSL::SSL::SSLError
+ raise Consul::Internal::SSLError
+ rescue Errno::ECONNREFUSED
+ raise Consul::Internal::ECONNREFUSED
+ rescue
+ raise Consul::Internal::UnexpectedResponseError
+ end
+ end
+ end
+ end
+end