diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-12 00:08:44 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-12 00:08:44 +0300 |
commit | a66475b6beb46d77b9ff3fe30453be2d52779048 (patch) | |
tree | 39fd943e67dd66b1d734028f5449d8a41c4fe58f /lib/gitlab/consul/internal.rb | |
parent | 48e26d30fd251f87a2e136d8997ef2ec35859e71 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/consul/internal.rb')
-rw-r--r-- | lib/gitlab/consul/internal.rb | 85 |
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 |