Skip to content

Commit

Permalink
Added unit test to validate the authenticity rules
Browse files Browse the repository at this point in the history
  • Loading branch information
andsel committed Jul 15, 2021
1 parent b5732d8 commit 2c6d745
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 3 deletions.
10 changes: 7 additions & 3 deletions lib/logstash/outputs/elasticsearch/http_client/pool.rb
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,12 @@ def healthcheck!
end

def elasticsearch?(url)
response = perform_request_to_url(url, :get, "/")
return false if response.code == 401 || response.code == 403
begin
response = perform_request_to_url(url, :get, "/")
rescue ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError => e
return false if response.code == 401 || response.code == 403
raise e
end

version_info = LogStash::Json.load(response.body)
return false if version_info['version'].nil?
Expand All @@ -281,7 +285,7 @@ def elasticsearch?(url)
return false if build_flavour.nil? || build_flavour != 'default' || !valid_tagline?(version_info)
else
# case >= 7.14
product_header = response.headers['X-elastic-product']
product_header = response.headers['x-elastic-product']
return false if product_header.nil? || product_header != 'Elasticsearch'
end
return true
Expand Down
1 change: 1 addition & 0 deletions logstash-output-elasticsearch.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'logstash-devutils'
s.add_development_dependency 'flores'
s.add_development_dependency 'cabin', ['~> 0.6']
s.add_development_dependency 'webmock'
# Still used in some specs, we should remove this ASAP
s.add_development_dependency 'elasticsearch'
end
123 changes: 123 additions & 0 deletions spec/unit/outputs/elasticsearch/http_client/pool_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require "logstash/devutils/rspec/spec_helper"
require "logstash/outputs/elasticsearch/http_client"
require 'cabin'
require 'webmock/rspec'

describe LogStash::Outputs::ElasticSearch::HttpClient::Pool do
let(:logger) { Cabin::Channel.get }
Expand Down Expand Up @@ -341,3 +342,125 @@ def code
end
end
end

describe "#elasticsearch?" do
let(:logger) { Cabin::Channel.get }
let(:adapter) { LogStash::Outputs::ElasticSearch::HttpClient::ManticoreAdapter.new(logger) }
let(:initial_urls) { [::LogStash::Util::SafeURI.new("http://localhost:9200")] }
let(:options) { {:resurrect_delay => 2, :url_normalizer => proc {|u| u}} } # Shorten the delay a bit to speed up tests
let(:es_node_versions) { [ "0.0.0" ] }
let(:license_status) { 'active' }

subject { LogStash::Outputs::ElasticSearch::HttpClient::Pool.new(logger, adapter, initial_urls, options) }

let(:url) { ::LogStash::Util::SafeURI.new("http://localhost:9200") }

context "in case HTTP error code" do
it "should fail for 401" do
stub_request(:get, "localhost:9200").to_return(status: 401)
expect(subject.elasticsearch?(url)).to be false

# # stub_request(:post, "www.example.com").
# # with(body: "abc", headers: { 'Content-Length' => 3 })
# #
# uri = URI.parse("http://localhost:9300/")
# # req = Net::HTTP::Get.new(uri.path)
# # req['Content-Length'] = 3
#
# #res = Net::HTTP.start(uri.host, uri.port) do |http|
# # http.request(req, "abc")
# #end
# res = Net::HTTP.get_response(uri)
# expect(res.class).to eq(Net::HTTPUnauthorized)
# expect(res).to be_a(Net::HTTPUnauthorized)
# puts "DNADBG>> HTTP net response: #{res}"
#
#
# # using Manticore
# manticore = ::Manticore::Client.new()
# #resp = manticore.get("http://localhost:9300/")
# resp = manticore.send("get", "http://localhost:9300/", {})
# resp.call
# puts "DNADBG>> Manticore response: #{resp.class}"
# puts "DNADBG>> resp.code: #{resp.code}"
# expect(resp.code).to eq(401)

end

it "should fail for 403" do
stub_request(:get, "localhost:9200").to_return(status: 403)
expect(subject.elasticsearch?(url)).to be false
end
end

context "when connecting to a cluster which reply without 'version' field" do
it "should fail" do
stub_request(:get, "localhost:9200").to_return(body: '{"field": "funky"}')
expect(subject.elasticsearch?(url)).to be false
end
end

context "when connecting to a cluster with version < 6.0.0" do
it "should fail" do
stub_request(:get, "localhost:9200").to_return(body: '{"version": {"number": "5.0.0"}}')
expect(subject.elasticsearch?(url)).to be false
end
end

context "when connecting to a cluster with version in [6.0.0..7.0.0)" do
it "must be successful with valid 'tagline'" do
stub_request(:get, "localhost:9200").to_return(status: 200, body: '{"version": {"number": "6.5.0"}, "tagline": "You Know, for Search"}')
expect(subject.elasticsearch?(url)).to be true
end

it "should fail if invalid 'tagline'" do
stub_request(:get, "localhost:9200").to_return(body: '{"version": {"number": "6.5.0"}, "tagline": "You don\'t know"}')
expect(subject.elasticsearch?(url)).to be false
end

it "should fail if 'tagline' is not present" do
stub_request(:get, "localhost:9200").to_return(body: '{"version": {"number": "6.5.0"}}')
expect(subject.elasticsearch?(url)).to be false
end
end

context "when connecting to a cluster with version in [7.0.0..7.14.0)" do
it "must be successful is 'build_flavour' is 'default' and tagline is correct" do
stub_request(:get, "localhost:9200/").to_return(status: 200, body: '{"version": {"number": "7.5.0", "build_flavour": "default"}, "tagline": "You Know, for Search"}')
expect(subject.elasticsearch?(url)).to be true
end

it "should fail if 'build_flavour' is not 'default' and tagline is correct" do
stub_request(:get, "localhost:9200").to_return(status: 200, body: '{"version": {"number": "7.5.0", "build_flavour": "oss"}, "tagline": "You Know, for Search"}')
expect(subject.elasticsearch?(url)).to be false
end

it "should fail if 'build_flavour' is not present and tagline is correct" do
stub_request(:get, "localhost:9200").to_return(status: 200, body: '{"version": {"number": "7.5.0"}, "tagline": "You Know, for Search"}')
expect(subject.elasticsearch?(url)).to be false
end
end

context "when connecting to a cluster with version >= 7.14.0" do
it "should fail if 'X-elastic-product' header is not present" do
stub_request(:get, "localhost:9200").to_return(status: 200, body: '{"version": {"number": "7.14.0"}}')
expect(subject.elasticsearch?(url)).to be false
end

it "should fail if 'X-elastic-product' header is present but with bad value" do
stub_request(:get, "localhost:9200")
.to_return(status: 200,
headers: {'X-elastic-product' => 'not good'},
body: '{"version": {"number": "7.14.0"}}')
expect(subject.elasticsearch?(url)).to be false
end

it "must be successful when 'X-elastic-product' header is present with expected value" do
stub_request(:get, "localhost:9200")
.to_return(status: 200,
headers: {'X-elastic-product': 'Elasticsearch'},
body: '{"version": {"number": "7.14.0"}}')
expect(subject.elasticsearch?(url)).to be true
end
end
end

0 comments on commit 2c6d745

Please sign in to comment.