fluent-plugin-elasticsearch-dext 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +2 -0
  3. data/.editorconfig +9 -0
  4. data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
  5. data/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
  6. data/.github/workflows/issue-auto-closer.yml +12 -0
  7. data/.github/workflows/linux.yml +26 -0
  8. data/.github/workflows/macos.yml +26 -0
  9. data/.github/workflows/windows.yml +26 -0
  10. data/.gitignore +18 -0
  11. data/.travis.yml +40 -0
  12. data/CONTRIBUTING.md +24 -0
  13. data/Gemfile +11 -0
  14. data/History.md +553 -0
  15. data/ISSUE_TEMPLATE.md +30 -0
  16. data/LICENSE.txt +201 -0
  17. data/PULL_REQUEST_TEMPLATE.md +10 -0
  18. data/README.ElasticsearchGenID.md +116 -0
  19. data/README.ElasticsearchInput.md +293 -0
  20. data/README.Troubleshooting.md +601 -0
  21. data/README.md +1467 -0
  22. data/Rakefile +11 -0
  23. data/appveyor.yml +20 -0
  24. data/fluent-plugin-elasticsearch.gemspec +35 -0
  25. data/gemfiles/Gemfile.elasticsearch.v6 +12 -0
  26. data/lib/fluent/log-ext.rb +38 -0
  27. data/lib/fluent/plugin/default-ilm-policy.json +14 -0
  28. data/lib/fluent/plugin/elasticsearch_constants.rb +13 -0
  29. data/lib/fluent/plugin/elasticsearch_error.rb +5 -0
  30. data/lib/fluent/plugin/elasticsearch_error_handler.rb +129 -0
  31. data/lib/fluent/plugin/elasticsearch_fallback_selector.rb +9 -0
  32. data/lib/fluent/plugin/elasticsearch_index_lifecycle_management.rb +67 -0
  33. data/lib/fluent/plugin/elasticsearch_index_template.rb +211 -0
  34. data/lib/fluent/plugin/elasticsearch_simple_sniffer.rb +10 -0
  35. data/lib/fluent/plugin/elasticsearch_tls.rb +70 -0
  36. data/lib/fluent/plugin/filter_elasticsearch_genid.rb +77 -0
  37. data/lib/fluent/plugin/in_elasticsearch.rb +325 -0
  38. data/lib/fluent/plugin/oj_serializer.rb +22 -0
  39. data/lib/fluent/plugin/out_elasticsearch.rb +1108 -0
  40. data/lib/fluent/plugin/out_elasticsearch_data_stream.rb +218 -0
  41. data/lib/fluent/plugin/out_elasticsearch_dynamic.rb +282 -0
  42. data/test/helper.rb +24 -0
  43. data/test/plugin/test_alias_template.json +9 -0
  44. data/test/plugin/test_elasticsearch_error_handler.rb +646 -0
  45. data/test/plugin/test_elasticsearch_fallback_selector.rb +74 -0
  46. data/test/plugin/test_elasticsearch_index_lifecycle_management.rb +66 -0
  47. data/test/plugin/test_elasticsearch_tls.rb +145 -0
  48. data/test/plugin/test_filter_elasticsearch_genid.rb +215 -0
  49. data/test/plugin/test_in_elasticsearch.rb +459 -0
  50. data/test/plugin/test_index_alias_template.json +11 -0
  51. data/test/plugin/test_index_template.json +25 -0
  52. data/test/plugin/test_oj_serializer.rb +19 -0
  53. data/test/plugin/test_out_elasticsearch.rb +5688 -0
  54. data/test/plugin/test_out_elasticsearch_data_stream.rb +337 -0
  55. data/test/plugin/test_out_elasticsearch_dynamic.rb +1134 -0
  56. data/test/plugin/test_template.json +23 -0
  57. data/test/test_log-ext.rb +35 -0
  58. metadata +236 -0
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'test'
6
+ test.pattern = 'test/**/test_*.rb'
7
+ test.verbose = true
8
+ test.warning = false
9
+ end
10
+
11
+ task :default => :test
data/appveyor.yml ADDED
@@ -0,0 +1,20 @@
1
+ version: '{build}'
2
+ install:
3
+ - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
4
+ - ridk.cmd enable
5
+ - ruby --version
6
+ - gem --version
7
+ - bundle install
8
+ build: off
9
+ test_script:
10
+ - bundle exec rake test
11
+
12
+ # https://www.appveyor.com/docs/installed-software/#ruby
13
+ environment:
14
+ matrix:
15
+ - ruby_version: "26-x64"
16
+ - ruby_version: "26"
17
+ - ruby_version: "25-x64"
18
+ - ruby_version: "25"
19
+ - ruby_version: "24-x64"
20
+ - ruby_version: "24"
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'fluent-plugin-elasticsearch-dext'
6
+ s.version = '5.0.2'
7
+ s.authors = ['diogo', 'pitr', 'Hiroshi Hatake', 'mihailgmihaylov']
8
+ s.email = ['pitr.vern@gmail.com', 'me@diogoterror.com', 'cosmo0920.wp@gmail.com', 'mihail.mihaylov@dext.com']
9
+ s.description = %q{Elasticsearch output plugin for Fluent event collector with small modification from Dext}
10
+ s.summary = s.description
11
+ s.homepage = 'https://github.com/wbrefvem/fluent-plugin-elasticsearch'
12
+ s.license = 'Apache-2.0'
13
+
14
+ s.files = `git ls-files`.split($/)
15
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
17
+ s.require_paths = ['lib']
18
+
19
+ if s.respond_to?(:metadata)
20
+ s.metadata["changelog_uri"] = "https://github.com/uken/fluent-plugin-elasticsearch/blob/master/History.md"
21
+ end
22
+
23
+ s.required_ruby_version = Gem::Requirement.new(">= 2.3".freeze)
24
+
25
+ s.add_runtime_dependency 'fluentd', '>= 0.14.22'
26
+ s.add_runtime_dependency 'excon', '>= 0'
27
+ s.add_runtime_dependency 'elasticsearch'
28
+
29
+
30
+ s.add_development_dependency 'rake', '>= 0'
31
+ s.add_development_dependency 'webmock', '~> 3'
32
+ s.add_development_dependency 'test-unit', '~> 3.3.0'
33
+ s.add_development_dependency 'minitest', '~> 5.8'
34
+ s.add_development_dependency 'flexmock', '~> 2.0'
35
+ end
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-elasticsearch.gemspec
4
+ gemspec :path => "../"
5
+
6
+ gem 'simplecov', require: false
7
+ gem 'coveralls', ">= 0.8.0", require: false
8
+ gem 'strptime', require: false if RUBY_ENGINE == "ruby" && RUBY_VERSION =~ /^2/
9
+ gem "irb" if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.6"
10
+ gem "elasticsearch", "~> 6.8.1"
11
+ gem "elasticsearch-xpack"
12
+ gem "oj"
@@ -0,0 +1,38 @@
1
+ require 'fluent/log'
2
+ # For elasticsearch-ruby v7.0.0 or later
3
+ # logger for Elasticsearch::Loggable required the following methods:
4
+ #
5
+ # * debug?
6
+ # * info?
7
+ # * warn?
8
+ # * error?
9
+ # * fatal?
10
+
11
+ module Fluent
12
+ class Log
13
+ # Elasticsearch::Loggable does not request trace? method.
14
+ # def trace?
15
+ # @level <= LEVEL_TRACE
16
+ # end
17
+
18
+ def debug?
19
+ @level <= LEVEL_DEBUG
20
+ end
21
+
22
+ def info?
23
+ @level <= LEVEL_INFO
24
+ end
25
+
26
+ def warn?
27
+ @level <= LEVEL_WARN
28
+ end
29
+
30
+ def error?
31
+ @level <= LEVEL_ERROR
32
+ end
33
+
34
+ def fatal?
35
+ @level <= LEVEL_FATAL
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,14 @@
1
+ {
2
+ "policy": {
3
+ "phases": {
4
+ "hot": {
5
+ "actions": {
6
+ "rollover": {
7
+ "max_size": "50gb",
8
+ "max_age": "30d"
9
+ }
10
+ }
11
+ }
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,13 @@
1
+ module Fluent
2
+ module Plugin
3
+ module ElasticsearchConstants
4
+ BODY_DELIMITER = "\n".freeze
5
+ UPDATE_OP = "update".freeze
6
+ UPSERT_OP = "upsert".freeze
7
+ CREATE_OP = "create".freeze
8
+ INDEX_OP = "index".freeze
9
+ ID_FIELD = "_id".freeze
10
+ TIMESTAMP_FIELD = "@timestamp".freeze
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ require 'fluent/error'
2
+
3
+ class Fluent::Plugin::ElasticsearchError
4
+ class RetryableOperationExhaustedFailure < Fluent::UnrecoverableError; end
5
+ end
@@ -0,0 +1,129 @@
1
+ require 'fluent/event'
2
+ require 'fluent/error'
3
+ require_relative 'elasticsearch_constants'
4
+
5
+ class Fluent::Plugin::ElasticsearchErrorHandler
6
+ include Fluent::Plugin::ElasticsearchConstants
7
+
8
+ attr_accessor :bulk_message_count
9
+ class ElasticsearchVersionMismatch < Fluent::UnrecoverableError; end
10
+ class ElasticsearchSubmitMismatch < Fluent::UnrecoverableError; end
11
+ class ElasticsearchRequestAbortError < Fluent::UnrecoverableError; end
12
+ class ElasticsearchError < StandardError; end
13
+
14
+ def initialize(plugin)
15
+ @plugin = plugin
16
+ end
17
+
18
+ def unrecoverable_error_types
19
+ @plugin.unrecoverable_error_types
20
+ end
21
+
22
+ def unrecoverable_error?(type)
23
+ unrecoverable_error_types.include?(type)
24
+ end
25
+
26
+ def log_es_400_reason(&block)
27
+ if @plugin.log_es_400_reason
28
+ block.call
29
+ else
30
+ @plugin.log.on_debug(&block)
31
+ end
32
+ end
33
+
34
+ def handle_error(response, tag, chunk, bulk_message_count, extracted_values)
35
+ items = response['items']
36
+ if items.nil? || !items.is_a?(Array)
37
+ raise ElasticsearchVersionMismatch, "The response format was unrecognized: #{response}"
38
+ end
39
+ if bulk_message_count != items.length
40
+ raise ElasticsearchSubmitMismatch, "The number of records submitted #{bulk_message_count} do not match the number returned #{items.length}. Unable to process bulk response."
41
+ end
42
+ retry_stream = Fluent::MultiEventStream.new
43
+ stats = Hash.new(0)
44
+ meta = {}
45
+ header = {}
46
+ chunk.msgpack_each do |time, rawrecord|
47
+ bulk_message = ''
48
+ next unless rawrecord.is_a? Hash
49
+ begin
50
+ # we need a deep copy for process_message to alter
51
+ processrecord = Marshal.load(Marshal.dump(rawrecord))
52
+ meta, header, record = @plugin.process_message(tag, meta, header, time, processrecord, extracted_values)
53
+ next unless @plugin.append_record_to_messages(@plugin.write_operation, meta, header, record, bulk_message)
54
+ rescue => e
55
+ stats[:bad_chunk_record] += 1
56
+ next
57
+ end
58
+ item = items.shift
59
+ if item.is_a?(Hash) && item.has_key?(@plugin.write_operation)
60
+ write_operation = @plugin.write_operation
61
+ elsif INDEX_OP == @plugin.write_operation && item.is_a?(Hash) && item.has_key?(CREATE_OP)
62
+ write_operation = CREATE_OP
63
+ elsif UPSERT_OP == @plugin.write_operation && item.is_a?(Hash) && item.has_key?(UPDATE_OP)
64
+ write_operation = UPDATE_OP
65
+ elsif item.nil?
66
+ stats[:errors_nil_resp] += 1
67
+ next
68
+ else
69
+ # When we don't have an expected ops field, something changed in the API
70
+ # expected return values (ES 2.x)
71
+ stats[:errors_bad_resp] += 1
72
+ next
73
+ end
74
+ if item[write_operation].has_key?('status')
75
+ status = item[write_operation]['status']
76
+ else
77
+ # When we don't have a status field, something changed in the API
78
+ # expected return values (ES 2.x)
79
+ stats[:errors_bad_resp] += 1
80
+ next
81
+ end
82
+ case
83
+ when [200, 201].include?(status)
84
+ stats[:successes] += 1
85
+ when CREATE_OP == write_operation && 409 == status
86
+ stats[:duplicates] += 1
87
+ when 400 == status
88
+ stats[:bad_argument] += 1
89
+ reason = ""
90
+ log_es_400_reason do
91
+ if item[write_operation].has_key?('error') && item[write_operation]['error'].has_key?('type')
92
+ reason = " [error type]: #{item[write_operation]['error']['type']}"
93
+ end
94
+ if item[write_operation].has_key?('error') && item[write_operation]['error'].has_key?('reason')
95
+ reason += " [reason]: \'#{item[write_operation]['error']['reason']}\'"
96
+ end
97
+ end
98
+ @plugin.router.emit_error_event(tag, time, rawrecord, ElasticsearchError.new("400 - Rejected by Elasticsearch#{reason}"))
99
+ else
100
+ if item[write_operation]['error'].is_a?(String)
101
+ reason = item[write_operation]['error']
102
+ stats[:errors_block_resp] += 1
103
+ @plugin.router.emit_error_event(tag, time, rawrecord, ElasticsearchError.new("#{status} - #{reason}"))
104
+ next
105
+ elsif item[write_operation].has_key?('error') && item[write_operation]['error'].has_key?('type')
106
+ type = item[write_operation]['error']['type']
107
+ stats[type] += 1
108
+ retry_stream.add(time, rawrecord)
109
+ if unrecoverable_error?(type)
110
+ raise ElasticsearchRequestAbortError, "Rejected Elasticsearch due to #{type}"
111
+ end
112
+ else
113
+ # When we don't have a type field, something changed in the API
114
+ # expected return values (ES 2.x)
115
+ stats[:errors_bad_resp] += 1
116
+ @plugin.router.emit_error_event(tag, time, rawrecord, ElasticsearchError.new("#{status} - No error type provided in the response"))
117
+ next
118
+ end
119
+ stats[type] += 1
120
+ end
121
+ end
122
+ @plugin.log.on_debug do
123
+ msg = ["Indexed (op = #{@plugin.write_operation})"]
124
+ stats.each_pair { |key, value| msg << "#{value} #{key}" }
125
+ @plugin.log.debug msg.join(', ')
126
+ end
127
+ raise Fluent::Plugin::ElasticsearchOutput::RetryStreamError.new(retry_stream) unless retry_stream.empty?
128
+ end
129
+ end
@@ -0,0 +1,9 @@
1
+ require 'elasticsearch/transport/transport/connections/selector'
2
+
3
+ class Fluent::Plugin::ElasticseatchFallbackSelector
4
+ include Elasticsearch::Transport::Transport::Connections::Selector::Base
5
+
6
+ def select(options={})
7
+ connections.first
8
+ end
9
+ end
@@ -0,0 +1,67 @@
1
+ module Fluent::Plugin::ElasticsearchIndexLifecycleManagement
2
+ ILM_DEFAULT_POLICY_PATH = "default-ilm-policy.json"
3
+
4
+ def setup_ilm(enable_ilm, policy_id, ilm_policy = default_policy_payload, overwrite = false)
5
+ return unless enable_ilm
6
+
7
+ create_ilm_policy(policy_id, ilm_policy, overwrite)
8
+ end
9
+
10
+ def verify_ilm_working
11
+ # Check the Elasticsearch instance for ILM readiness - this means that the version has to be a non-OSS release, with ILM feature
12
+ # available and enabled.
13
+ begin
14
+ xpack = xpack_info
15
+ if xpack.nil?
16
+ raise Fluent::ConfigError, "xpack endpoint does not work"
17
+ end
18
+ features = xpack["features"]
19
+ ilm = features.nil? ? nil : features["ilm"]
20
+ raise Fluent::ConfigError, "Index Lifecycle management is enabled in Fluentd, but not installed on your Elasticsearch" if features.nil? || ilm.nil?
21
+ raise Fluent::ConfigError, "Index Lifecycle management is enabled in Fluentd, but not available in your Elasticsearch" unless ilm['available']
22
+ raise Fluent::ConfigError, "Index Lifecycle management is enabled in Fluentd, but not enabled in your Elasticsearch" unless ilm['enabled']
23
+
24
+ rescue Elasticsearch::Transport::Transport::Error => e
25
+ raise Fluent::ConfigError, "Index Lifecycle management is enabled in Fluentd, but not installed on your Elasticsearch", error: e
26
+ end
27
+ end
28
+
29
+ def create_ilm_policy(policy_id, ilm_policy = default_policy_payload, overwrite = false)
30
+ if overwrite || !ilm_policy_exists?(policy_id)
31
+ ilm_policy_put(policy_id, ilm_policy)
32
+ end
33
+ end
34
+
35
+ def xpack_info
36
+ begin
37
+ client.xpack.info
38
+ rescue NoMethodError
39
+ raise RuntimeError, "elasticsearch-xpack gem is not installed."
40
+ rescue
41
+ nil
42
+ end
43
+ end
44
+
45
+ def get_ilm_policy
46
+ client.ilm.get_policy
47
+ end
48
+
49
+ def ilm_policy_exists?(policy_id)
50
+ begin
51
+ client.ilm.get_policy(policy_id: policy_id)
52
+ true
53
+ rescue
54
+ false
55
+ end
56
+ end
57
+
58
+ def ilm_policy_put(policy_id, policy)
59
+ log.info("Installing ILM policy: #{policy}")
60
+ client.ilm.put_policy(policy_id: policy_id, body: policy)
61
+ end
62
+
63
+ def default_policy_payload
64
+ default_policy_path = File.join(__dir__, ILM_DEFAULT_POLICY_PATH)
65
+ Yajl.load(::IO.read(default_policy_path))
66
+ end
67
+ end
@@ -0,0 +1,211 @@
1
+ require 'fluent/error'
2
+ require_relative './elasticsearch_error'
3
+
4
+ module Fluent::ElasticsearchIndexTemplate
5
+ def get_template(template_file)
6
+ if !File.exists?(template_file)
7
+ raise "If you specify a template_name you must specify a valid template file (checked '#{template_file}')!"
8
+ end
9
+ file_contents = IO.read(template_file).gsub(/\n/,'')
10
+ JSON.parse(file_contents)
11
+ end
12
+
13
+ def get_custom_template(template_file, customize_template)
14
+ if !File.exists?(template_file)
15
+ raise "If you specify a template_name you must specify a valid template file (checked '#{template_file}')!"
16
+ end
17
+ file_contents = IO.read(template_file).gsub(/\n/,'')
18
+ customize_template.each do |key, value|
19
+ file_contents = file_contents.gsub(key,value.downcase)
20
+ end
21
+ JSON.parse(file_contents)
22
+ end
23
+
24
+ def template_exists?(name, host = nil)
25
+ if @use_legacy_template
26
+ client(host).indices.get_template(:name => name)
27
+ else
28
+ client(host).indices.get_index_template(:name => name)
29
+ end
30
+ return true
31
+ rescue Elasticsearch::Transport::Transport::Errors::NotFound
32
+ return false
33
+ end
34
+
35
+ def retry_operate(max_retries, fail_on_retry_exceed = true, catch_trasport_exceptions = true)
36
+ return unless block_given?
37
+ retries = 0
38
+ transport_errors = Elasticsearch::Transport::Transport::Errors.constants.map{ |c| Elasticsearch::Transport::Transport::Errors.const_get c } if catch_trasport_exceptions
39
+ begin
40
+ yield
41
+ rescue *client.transport.host_unreachable_exceptions, *transport_errors, Timeout::Error => e
42
+ @_es = nil
43
+ @_es_info = nil
44
+ if retries < max_retries
45
+ retries += 1
46
+ wait_seconds = 2**retries
47
+ sleep wait_seconds
48
+ log.warn "Could not communicate to Elasticsearch, resetting connection and trying again. #{e.message}"
49
+ log.warn "Remaining retry: #{max_retries - retries}. Retry to communicate after #{wait_seconds} second(s)."
50
+ retry
51
+ end
52
+ message = "Could not communicate to Elasticsearch after #{retries} retries. #{e.message}"
53
+ log.warn message
54
+ raise Fluent::Plugin::ElasticsearchError::RetryableOperationExhaustedFailure,
55
+ message if fail_on_retry_exceed
56
+ end
57
+ end
58
+
59
+ def template_put(name, template, host = nil)
60
+ if @use_legacy_template
61
+ client(host).indices.put_template(:name => name, :body => template)
62
+ else
63
+ client(host).indices.put_index_template(:name => name, :body => template)
64
+ end
65
+ end
66
+
67
+ def indexcreation(index_name, host = nil)
68
+ client(host).indices.create(:index => index_name)
69
+ rescue Elasticsearch::Transport::Transport::Error => e
70
+ if e.message =~ /"already exists"/ || e.message =~ /resource_already_exists_exception/
71
+ log.debug("Index #{index_name} already exists")
72
+ else
73
+ log.error("Error while index creation - #{index_name}", error: e)
74
+ end
75
+ end
76
+
77
+ def template_install(name, template_file, overwrite, enable_ilm = false, deflector_alias_name = nil, ilm_policy_id = nil, host = nil, target_index = nil, index_separator = '-')
78
+ inject_template_name = get_template_name(enable_ilm, name, deflector_alias_name)
79
+ if overwrite
80
+ template_put(inject_template_name,
81
+ enable_ilm ? inject_ilm_settings_to_template(deflector_alias_name,
82
+ target_index,
83
+ ilm_policy_id,
84
+ get_template(template_file),
85
+ index_separator) :
86
+ get_template(template_file), host)
87
+
88
+ log.debug("Template '#{inject_template_name}' overwritten with #{template_file}.")
89
+ return
90
+ end
91
+ if !template_exists?(inject_template_name, host)
92
+ template_put(inject_template_name,
93
+ enable_ilm ? inject_ilm_settings_to_template(deflector_alias_name,
94
+ target_index,
95
+ ilm_policy_id,
96
+ get_template(template_file),
97
+ index_separator) :
98
+ get_template(template_file), host)
99
+ log.info("Template configured, but no template installed. Installed '#{inject_template_name}' from #{template_file}.")
100
+ else
101
+ log.debug("Template '#{inject_template_name}' configured and already installed.")
102
+ end
103
+ end
104
+
105
+ def template_custom_install(template_name, template_file, overwrite, customize_template, enable_ilm, deflector_alias_name, ilm_policy_id, host, target_index, index_separator)
106
+ template_custom_name = get_template_name(enable_ilm, template_name, deflector_alias_name)
107
+ custom_template = if enable_ilm
108
+ inject_ilm_settings_to_template(deflector_alias_name,
109
+ target_index,
110
+ ilm_policy_id,
111
+ get_custom_template(template_file,
112
+ customize_template),
113
+ index_separator)
114
+ else
115
+ get_custom_template(template_file, customize_template)
116
+ end
117
+ if overwrite
118
+ template_put(template_custom_name, custom_template, host)
119
+ log.info("Template '#{template_custom_name}' overwritten with #{template_file}.")
120
+ else
121
+ if !template_exists?(template_custom_name, host)
122
+ template_put(template_custom_name, custom_template, host)
123
+ log.info("Template configured, but no template installed. Installed '#{template_custom_name}' from #{template_file}.")
124
+ else
125
+ log.debug("Template '#{template_custom_name}' configured and already installed.")
126
+ end
127
+ end
128
+ end
129
+
130
+ def get_template_name(enable_ilm, template_name, deflector_alias_name)
131
+ enable_ilm ? deflector_alias_name : template_name
132
+ end
133
+
134
+ def inject_ilm_settings_to_template(deflector_alias, target_index, ilm_policy_id, template, index_separator)
135
+ log.debug("Overwriting index patterns when Index Lifecycle Management is enabled.")
136
+ template['index_patterns'] = "#{target_index}#{index_separator}*"
137
+ if @use_legacy_template
138
+ template.delete('template') if template.include?('template')
139
+ # Prepare settings Hash
140
+ if !template.key?('settings')
141
+ template['settings'] = {}
142
+ end
143
+ if template['settings'] && (template['settings']['index.lifecycle.name'] || template['settings']['index.lifecycle.rollover_alias'])
144
+ log.debug("Overwriting index lifecycle name and rollover alias when Index Lifecycle Management is enabled.")
145
+ end
146
+ template['settings'].update({ 'index.lifecycle.name' => ilm_policy_id, 'index.lifecycle.rollover_alias' => deflector_alias})
147
+ template['order'] = template['order'] ? template['order'] + target_index.count(index_separator) + 1 : 51 + target_index.count(index_separator)
148
+ else
149
+ # Prepare template.settings Hash
150
+ if !template['template'].key?('settings')
151
+ template['template']['settings'] = {}
152
+ end
153
+ if template['template']['settings'] && (template['template']['settings']['index.lifecycle.name'] || template['template']['settings']['index.lifecycle.rollover_alias'])
154
+ log.debug("Overwriting index lifecycle name and rollover alias when Index Lifecycle Management is enabled.")
155
+ end
156
+ template['template']['settings'].update({ 'index.lifecycle.name' => ilm_policy_id, 'index.lifecycle.rollover_alias' => deflector_alias})
157
+ template['priority'] = template['priority'] ? template['priority'] + target_index.count(index_separator) + 1 : 101 + target_index.count(index_separator)
158
+ end
159
+ template
160
+ end
161
+
162
+ def create_rollover_alias(target_index, rollover_index, deflector_alias_name, app_name, index_date_pattern, index_separator, enable_ilm, ilm_policy_id, ilm_policy, ilm_policy_overwrite, host)
163
+ # ILM request to create alias.
164
+ if rollover_index || enable_ilm
165
+ if !client.indices.exists_alias(:name => deflector_alias_name)
166
+ if @logstash_format
167
+ index_name_temp = '<'+target_index+'-000001>'
168
+ else
169
+ if index_date_pattern.empty?
170
+ index_name_temp = '<'+target_index.downcase+index_separator+app_name.downcase+'-000001>'
171
+ else
172
+ index_name_temp = '<'+target_index.downcase+index_separator+app_name.downcase+'-{'+index_date_pattern+'}-000001>'
173
+ end
174
+ end
175
+ indexcreation(index_name_temp, host)
176
+ body = rollover_alias_payload(deflector_alias_name)
177
+ client.indices.put_alias(:index => index_name_temp, :name => deflector_alias_name,
178
+ :body => body)
179
+ log.info("The alias '#{deflector_alias_name}' is created for the index '#{index_name_temp}'")
180
+ else
181
+ log.debug("The alias '#{deflector_alias_name}' is already present")
182
+ end
183
+ # Create ILM policy if rollover indices exist.
184
+ if enable_ilm
185
+ if ilm_policy.empty?
186
+ setup_ilm(enable_ilm, ilm_policy_id)
187
+ else
188
+ setup_ilm(enable_ilm, ilm_policy_id, ilm_policy, ilm_policy_overwrite)
189
+ end
190
+ end
191
+ else
192
+ log.debug("No index and alias creation action performed because rollover_index or enable_ilm is set to: '#{rollover_index}', '#{enable_ilm}'")
193
+ end
194
+ end
195
+
196
+ def templates_hash_install(templates, overwrite)
197
+ templates.each do |key, value|
198
+ template_install(key, value, overwrite)
199
+ end
200
+ end
201
+
202
+ def rollover_alias_payload(rollover_alias)
203
+ {
204
+ 'aliases' => {
205
+ rollover_alias => {
206
+ 'is_write_index' => true
207
+ }
208
+ }
209
+ }
210
+ end
211
+ end