mirror of
https://github.com/elastic/logstash.git
synced 2025-04-19 04:15:23 -04:00
Enabled: * SpaceInsideArrayLiteralBrackets * SpaceInsideParens * SpaceInsidePercentLiteralDelimiters * SpaceInsideStringInterpolation * Add enforced style for SpaceInsideStringInterpolation Enabled without offenses: * SpaceInsideArrayPercentLiteral * Layout/SpaceInsideRangeLiteral * Layout/SpaceInsideReferenceBrackets
173 lines
7 KiB
Ruby
173 lines
7 KiB
Ruby
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
# or more contributor license agreements. Licensed under the Elastic License;
|
|
# you may not use this file except in compliance with the Elastic License.
|
|
|
|
require "spec_helper"
|
|
require 'support/helpers'
|
|
require "license_checker/license_reader"
|
|
require "helpers/elasticsearch_options"
|
|
require "monitoring/monitoring"
|
|
require "logstash/runner"
|
|
|
|
describe LogStash::LicenseChecker::LicenseReader do
|
|
let(:elasticsearch_url) { "https://localhost:9898" }
|
|
let(:elasticsearch_username) { "elastictest" }
|
|
let(:elasticsearch_password) { "testchangeme" }
|
|
let(:extension) { LogStash::MonitoringExtension.new }
|
|
let(:system_settings) do
|
|
LogStash::Runner::SYSTEM_SETTINGS.clone.tap do |system_settings|
|
|
extension.additionals_settings(system_settings) # register defaults from extension
|
|
apply_settings(settings, system_settings) # apply `settings`
|
|
end
|
|
end
|
|
let(:product_origin_header) { { "x-elastic-product-origin" => "logstash" } }
|
|
|
|
let(:settings) do
|
|
{
|
|
"xpack.monitoring.enabled" => true,
|
|
"xpack.monitoring.elasticsearch.hosts" => [elasticsearch_url],
|
|
"xpack.monitoring.elasticsearch.username" => elasticsearch_username,
|
|
"xpack.monitoring.elasticsearch.password" => elasticsearch_password,
|
|
}
|
|
end
|
|
|
|
# TODO: fix indirection
|
|
# by the time the LicenseReader is initialized, a Hash of es_options for the feature
|
|
# have already been extracted from the given Settings, and while the Settings required
|
|
# they are not actually used.
|
|
let(:elasticsearch_options) do
|
|
LogStash::Helpers::ElasticsearchOptions.es_options_from_settings('monitoring', system_settings)
|
|
end
|
|
|
|
before(:each) do
|
|
# We do _not_ want the client's connection pool to start on initialization, as error conditions
|
|
# from accidentally succeeding at establishing a connection to an HTTP resource that's not actually
|
|
# a live Elasticsearch (e.g., reaped cloud instance) can cause errors.
|
|
allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:start)
|
|
end
|
|
|
|
subject { described_class.new(system_settings, 'monitoring', elasticsearch_options) }
|
|
|
|
describe '#fetch_xpack_info' do
|
|
let(:xpack_info_class) { LogStash::LicenseChecker::XPackInfo }
|
|
let(:mock_client) { double('Client') }
|
|
before(:each) { expect(subject).to receive(:client).and_return(mock_client).at_most(:twice) }
|
|
let(:xpack_info) do
|
|
{
|
|
"license" => {},
|
|
"features" => {},
|
|
}
|
|
end
|
|
|
|
context 'when client fetches xpack info' do
|
|
before(:each) do
|
|
expect(mock_client).to receive(:get).with('_xpack').and_return(xpack_info)
|
|
end
|
|
it 'returns an XPackInfo' do
|
|
expect(subject.fetch_xpack_info).to eq(xpack_info_class.from_es_response(xpack_info))
|
|
end
|
|
end
|
|
|
|
context 'and receives HostUnreachableError' do
|
|
let(:host_not_reachable) { LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError.new(StandardError.new("original error"), "http://localhost:19200") }
|
|
before(:each) do
|
|
# set up expectation of single failure
|
|
expect(subject.logger).to receive(:warn).with(a_string_starting_with("Attempt to validate Elasticsearch license failed."), any_args)
|
|
expect(mock_client).to receive(:get).with('_xpack').and_raise(host_not_reachable).once
|
|
|
|
# ensure subsequent success
|
|
expect(mock_client).to receive(:get).with('_xpack').and_return(xpack_info)
|
|
end
|
|
it 'continues to fetch and return an XPackInfo' do
|
|
expect(subject.fetch_xpack_info.failed?).to be false
|
|
end
|
|
end
|
|
context 'when client raises a ConnectionError' do
|
|
before(:each) do
|
|
expect(mock_client).to receive(:get).with('_xpack').and_raise(Puma::ConnectionError)
|
|
end
|
|
it 'returns failed to fetch' do
|
|
expect(subject.fetch_xpack_info.failed?).to be_truthy
|
|
end
|
|
end
|
|
context 'when client raises a 5XX' do
|
|
let(:exception_500) { LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError.new(500, '', '', '') }
|
|
before(:each) do
|
|
expect(mock_client).to receive(:get).with('_xpack').and_raise(exception_500)
|
|
end
|
|
it 'returns nil' do
|
|
expect(subject.fetch_xpack_info.failed?).to be_truthy
|
|
end
|
|
end
|
|
context 'when client raises a 404' do
|
|
let(:exception_404) do
|
|
LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError.new(404, '', '', '')
|
|
end
|
|
before(:each) do
|
|
expect(mock_client).to receive(:get).with('_xpack').and_raise(exception_404)
|
|
end
|
|
it 'returns an XPackInfo indicating that X-Pack is not installed' do
|
|
expect(subject.fetch_xpack_info).to eq(xpack_info_class.xpack_not_installed)
|
|
end
|
|
end
|
|
context 'when client returns a 404' do
|
|
# TODO: really, dawg? which is it? exceptions or not?
|
|
let(:body_404) do
|
|
{"status" => 404}
|
|
end
|
|
before(:each) do
|
|
expect(mock_client).to receive(:get).with('_xpack').and_return(body_404)
|
|
end
|
|
it 'returns an XPackInfo indicating that X-Pack is not installed' do
|
|
expect(subject.fetch_xpack_info).to eq(xpack_info_class.xpack_not_installed)
|
|
end
|
|
end
|
|
end
|
|
|
|
it "builds ES client" do
|
|
expect(subject.client.options[:hosts].size).to eql 1
|
|
expect(subject.client.options[:hosts][0].to_s).to eql elasticsearch_url # URI#to_s
|
|
expect(subject.client.options).to include(:user => elasticsearch_username, :password => elasticsearch_password)
|
|
expect(subject.client.client_settings[:headers]).to include(product_origin_header)
|
|
end
|
|
|
|
context 'with cloud_id' do
|
|
let(:cloud_id) do
|
|
'westeurope-1:d2VzdGV1cm9wZS5henVyZS5lbGFzdGljLWNsb3VkLmNvbTo5MjQzJGUxZTYzMTIwMWZiNjRkNTVhNzVmNDMxZWI2MzQ5NTg5JDljYzYwMGUwMGQwYjRhMThiNmY2NmU2ZTcyMTQwODA3'
|
|
end
|
|
let(:cloud_auth) do
|
|
'elastic:LnWMLeK3EQPTf3G3F1IBdFvO'
|
|
end
|
|
|
|
let(:settings) do
|
|
{
|
|
"xpack.monitoring.enabled" => true,
|
|
"xpack.monitoring.elasticsearch.cloud_id" => cloud_id,
|
|
"xpack.monitoring.elasticsearch.cloud_auth" => cloud_auth
|
|
}
|
|
end
|
|
|
|
it "builds ES client" do
|
|
expect(subject.client.options[:hosts].size).to eql 1
|
|
expect(subject.client.options[:hosts][0].to_s).to eql 'https://e1e631201fb64d55a75f431eb6349589.westeurope.azure.elastic-cloud.com:9243'
|
|
expect(subject.client.options).to include(:user => 'elastic', :password => 'LnWMLeK3EQPTf3G3F1IBdFvO')
|
|
expect(subject.client.client_settings[:headers]).to include(product_origin_header)
|
|
end
|
|
end
|
|
|
|
context 'with api_key' do
|
|
let(:api_key) { "foo:bar" }
|
|
let(:settings) do
|
|
{
|
|
"xpack.monitoring.enabled" => true,
|
|
"xpack.monitoring.elasticsearch.hosts" => [elasticsearch_url],
|
|
"xpack.monitoring.elasticsearch.api_key" => api_key,
|
|
}
|
|
end
|
|
|
|
it "builds ES client" do
|
|
expect(subject.client.client_settings[:headers]).to include("Authorization" => "ApiKey Zm9vOmJhcg==")
|
|
expect(subject.client.client_settings[:headers]).to include(product_origin_header)
|
|
end
|
|
end
|
|
end
|