-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This script will change the default timezone used by Kibana to display timestamps. It emits a proper setting directly into the `.kibana` index stored in elasticsearch. It will also create a `.kibana` index if one doesn't exist, with the default settings normally used by Kibana: 1 shard with 1 replica only. After the release of Kibana 5 we will refactor this script to use Kibana API: elastic/kibana#6849 Test that the script produces the expected exit codes and hits the expected endpoints. We run the script under test in a separate process since that is closer to reality. This requires us to mock http endpoints using a real http server. We had to upgrade `mimic` and work around a few design issues as the tooling for doing this isn't very good. We might want to reconsider how we do this sort of testing if we have to do a lot of it. @combor & @benhyland
- Loading branch information
Showing
3 changed files
with
205 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#! /usr/bin/env ruby | ||
|
||
require 'net/http' | ||
require 'json' | ||
|
||
def config_uri(es_url) | ||
config_url = "#{es_url}/.kibana/config/4.3.1" | ||
URI(config_url) | ||
end | ||
|
||
def index_settings_uri(es_url) | ||
index_settings_url = "#{es_url}/.kibana" | ||
URI(index_settings_url) | ||
end | ||
|
||
def update_es_index(uri, document) | ||
send_request( | ||
uri: uri, | ||
http_method: :Put, | ||
body: document, | ||
allowed_response_codes: ['200', '201'] | ||
) | ||
end | ||
|
||
def send_request(uri:, http_method:, allowed_response_codes:, body: nil) | ||
raise "Document is not a hash: #{body}" unless body == nil || body.is_a?(Hash) | ||
response = nil | ||
Net::HTTP.new(uri.host, uri.port).start do |http| | ||
method = Net::HTTP.const_get(http_method) | ||
headers = body ? { 'Content-Type' => 'application/json' } : {} | ||
req = method.new(uri.path, headers) | ||
req.body = body.to_json if body | ||
response = http.request(req) | ||
unless allowed_response_codes.include?(response.code) | ||
raise "Unexpected response code: #{response.code}\n#{response.body}" | ||
end | ||
end | ||
response | ||
end | ||
|
||
def need_to_create_index(response) | ||
!response["found"] | ||
end | ||
|
||
def need_to_set_timezone(response) | ||
!response["_source"] || response["_source"]["dateFormat:tz"] != "UTC" | ||
end | ||
|
||
def set_utc_config | ||
es_host = ENV.fetch("ES_HOST") | ||
es_port = ENV.fetch("ES_PORT") | ||
|
||
es_url = "http://#{es_host}:#{es_port}" | ||
|
||
config_uri = config_uri(es_url) | ||
response = send_request(uri: config_uri, http_method: :Get, allowed_response_codes: ['200', '404']) | ||
response_json = JSON.parse(response.body) | ||
|
||
if need_to_create_index(response_json) | ||
index_settings = { | ||
settings: { | ||
index: { | ||
number_of_shards: 1, | ||
number_of_replicas: 1, | ||
} | ||
} | ||
} | ||
update_es_index(index_settings_uri(es_url), index_settings) | ||
end | ||
|
||
if need_to_set_timezone(response_json) | ||
update_es_index(config_uri(es_url), { "dateFormat:tz" => "UTC" }) | ||
end | ||
end | ||
|
||
set_utc_config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
require 'mimic' | ||
|
||
RSpec.describe "kibana_set_utc.rb", :type => :aruba do | ||
|
||
ES_HOST = "127.0.0.1" | ||
ES_PORT = "9200" | ||
KIBANA_CONFIG_PATH = "/.kibana/config/4.3.1" | ||
KIBANA_INDEX_PATH = "/.kibana" | ||
|
||
Thread.abort_on_exception = true | ||
|
||
def run_set_utc_script | ||
run("./kibana_set_utc.rb") | ||
end | ||
|
||
before :all do | ||
@elasticsearch = Mimic.mimic(:hostname => ES_HOST, :port => ES_PORT) | ||
set_environment_variable 'ES_HOST', ES_HOST | ||
set_environment_variable 'ES_PORT', ES_PORT | ||
end | ||
|
||
after :each do | ||
Mimic.reset_all! | ||
end | ||
|
||
after :all do | ||
Mimic.cleanup! | ||
end | ||
|
||
it "creates index and adds utc config if no index exists" do | ||
|
||
@elasticsearch.instance_variable_get(:@app).not_found do | ||
# override the not_found handler provided by mimic, | ||
# so that we don't emit an empty body instead of the json we want with the 404 | ||
[404, {}, nil] | ||
end | ||
|
||
@elasticsearch.get(KIBANA_CONFIG_PATH).returning('{ "found": false }', 404) | ||
@elasticsearch.put(KIBANA_INDEX_PATH).returning('{}', 201) | ||
@elasticsearch.put(KIBANA_CONFIG_PATH).returning('{}', 201) | ||
|
||
run_set_utc_script | ||
|
||
expect(last_command_started).to have_exit_status(0) | ||
expect(@elasticsearch.received_requests.size).to be(3) | ||
expect(@elasticsearch.received_requests).to contain_request('GET', KIBANA_CONFIG_PATH) | ||
expect(@elasticsearch.received_requests).to contain_request('PUT', KIBANA_INDEX_PATH) | ||
expect(@elasticsearch.received_requests).to contain_request('PUT', KIBANA_CONFIG_PATH) | ||
end | ||
|
||
it "adds utc config if index exists but config is not present" do | ||
@elasticsearch.get(KIBANA_CONFIG_PATH).returning('{ "found": true }', 200) | ||
@elasticsearch.put(KIBANA_CONFIG_PATH).returning('{}', 200) | ||
|
||
run_set_utc_script | ||
|
||
expect(last_command_started).to have_exit_status(0) | ||
|
||
expect(@elasticsearch.received_requests.size).to be(2) | ||
expect(@elasticsearch.received_requests).to contain_request('GET', KIBANA_CONFIG_PATH) | ||
expect(@elasticsearch.received_requests).to contain_request('PUT', KIBANA_CONFIG_PATH) | ||
end | ||
|
||
it "adds utc config if index exists and wrong config is present" do | ||
@elasticsearch.get(KIBANA_CONFIG_PATH).returning('{ "found": true, "_source": { "dateFormat:tz": "NOT_UTC" } }', 200) | ||
@elasticsearch.put(KIBANA_CONFIG_PATH).returning('{}', 200) | ||
|
||
run_set_utc_script | ||
|
||
expect(last_command_started).to have_exit_status(0) | ||
|
||
expect(@elasticsearch.received_requests.size).to be(2) | ||
expect(@elasticsearch.received_requests).to contain_request('GET', KIBANA_CONFIG_PATH) | ||
expect(@elasticsearch.received_requests).to contain_request('PUT', KIBANA_CONFIG_PATH) | ||
end | ||
|
||
it "reports an error if elastic search is not available" do | ||
|
||
run_set_utc_script | ||
|
||
expect(last_command_started).to have_exit_status(1) | ||
expect(@elasticsearch.received_requests.size).to be(0) | ||
end | ||
|
||
it "does nothing if index exists and config is already UTC" do | ||
@elasticsearch.get(KIBANA_CONFIG_PATH).returning('{ "found": true, "_source": { "dateFormat:tz": "UTC" } }', 200) | ||
|
||
run_set_utc_script | ||
|
||
expect(last_command_started).to have_exit_status(0) | ||
|
||
expect(@elasticsearch.received_requests.size).to be(1) | ||
expect(@elasticsearch.received_requests).to contain_request('GET', KIBANA_CONFIG_PATH) | ||
end | ||
|
||
it "reports an error if elastic search responds with an unexpected status code" do | ||
@elasticsearch.get(KIBANA_CONFIG_PATH).returning('{ "found": true, "_source": { "dateFormat:tz": "UTC" } }', 500) | ||
|
||
run_set_utc_script | ||
|
||
expect(last_command_started).to have_exit_status(1) | ||
|
||
expect(@elasticsearch.received_requests.size).to be(1) | ||
expect(@elasticsearch.received_requests).to contain_request('GET', KIBANA_CONFIG_PATH) | ||
end | ||
|
||
matcher :contain_request do |expected_method, expected_path| | ||
match do |requests| | ||
requests.any? do |request| | ||
actual_path = request.instance_variable_get(:@path) | ||
actual_method = request.instance_variable_get(:@method) | ||
actual_method == expected_method && actual_path == expected_path | ||
end | ||
end | ||
end | ||
end |