elastic_manager 0.1.3 → 0.1.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 59956a9221433200e4da7152617c039ac1dde775d30299876b6bb379a2358fde
4
- data.tar.gz: c26c03c09b73188ef4e833a580981f538949918538e7df072f74a6eb5d55fd47
3
+ metadata.gz: 94343d3bac2671d6a49463c67d406afb79738edd347b63899ae32bcb58b1ac5e
4
+ data.tar.gz: aa36442960604bf810217e82d18c927db87d457e4d4c608202d85870ed190673
5
5
  SHA512:
6
- metadata.gz: a4b322f736dcc9fea634113b7f661e49827e8baf26ccdcbd0e8f0c40c2e44c21fc5bf146abf04a751f8321fa157156f5a5fa4f6bfd6165edc89f96a3604103af
7
- data.tar.gz: 6a06140123e5dc85b40b21ce47d115982c7293d6518ace6332614fcbba7e6a02b6d5b31636505d16a10a88c4bdb1210a140aa0612224e1a130fe164a81d4bb5c
6
+ metadata.gz: 892bf769d7e3392b4ce3dea9d3062b4ee3c2d7bb0335008478a6444d0b51c61d872b0d202ded7e978c854533b2150f08e560dacbf7dc04eb514d4bc9225358ef
7
+ data.tar.gz: aadad9042c0bd64848daf39c746639d3e8edcc0ad681686941ecd413324cba29375fdb1c586423abc727fef2e04cbaffe64b171f93c3cb1729640bf2763e0563
data/bin/elastic_manager CHANGED
@@ -6,4 +6,4 @@ STDOUT.sync = true
6
6
 
7
7
  elastic_manager = ElasticManager.new(ARGV)
8
8
 
9
- elastic_manager.work
9
+ elastic_manager.run
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'elastic_manager'
3
3
  s.executables = ['elastic_manager']
4
- s.version = '0.1.3'
4
+ s.version = '0.1.4'
5
5
  s.date = '2018-10-15'
6
6
  s.summary = 'Because qurator sucks'
7
7
  s.description = 'Manager for logstash indices in elastic'
@@ -0,0 +1,18 @@
1
+ module Close
2
+ def do_close(indices, date)
3
+ indices.each do |index_name|
4
+ next if skip?('close', index_name)
5
+
6
+ index = "#{index_name}-#{date}"
7
+ response = @elastic.request(:get, "/_cat/indices/#{index}")
8
+
9
+ if index_exist?(response)
10
+ next if already?('close', response, index)
11
+
12
+ action_with_log('close', index)
13
+ else
14
+ log.warn "#{index} index not found, maybe already snapshoted"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -35,15 +35,6 @@ module Config
35
35
  default
36
36
  end
37
37
 
38
- def parse_settings(json)
39
- begin
40
- JSON.parse(json)
41
- rescue JSON::ParserError => e
42
- log.fatal "json parse err: '''#{e.message}'''\n\t#{e.backtrace.join("\n\t")}"
43
- exit 1
44
- end
45
- end
46
-
47
38
  def option_parser(result)
48
39
  OptionParser.new do |parser|
49
40
  MAIN_PARAMS.each do |param|
@@ -60,7 +51,7 @@ module Config
60
51
  result[params[0].downcase][params[1].downcase] = pr
61
52
  elsif params.length == 1
62
53
  if params[0].downcase == 'settings'
63
- result[params[0].downcase] = parse_settings(pr)
54
+ result[params[0].downcase] = json_parse(pr)
64
55
  else
65
56
  result[params[0].downcase] = pr
66
57
  end
@@ -72,46 +63,54 @@ module Config
72
63
  result
73
64
  end
74
65
 
75
- def load_from_env
76
- log.debug "will load config from ENV variables"
66
+ def get_env_vars(var, result)
67
+ vars = var.split('_')
77
68
 
78
- result = make_default_config
69
+ if vars.length == 2
70
+ result[vars[0].downcase][vars[1].downcase] = ENV[var]
71
+ elsif vars.length == 1
72
+ if vars[0].downcase == 'settings'
73
+ result[vars[0].downcase] = json_parse(ENV[var])
74
+ else
75
+ result[vars[0].downcase] = ENV[var]
76
+ end
77
+ end
79
78
 
79
+ result
80
+ end
81
+
82
+ def env_parser(result)
80
83
  MAIN_PARAMS.each do |var|
81
84
  if ENV[var] == '' || ENV[var].nil?
82
85
  log.fatal BANNER_ENV
83
86
  exit 1
84
- else
85
- result[var.downcase] = ENV[var]
86
87
  end
88
+
89
+ result[var.downcase] = ENV[var]
87
90
  end
88
91
 
89
92
  ADDITIONAL_PARAMS.each do |var|
90
- unless ENV[var] == '' || ENV[var].nil?
91
- vars = var.split('_')
92
-
93
- if vars.length == 2
94
- result[vars[0].downcase][vars[1].downcase] = ENV[var]
95
- elsif vars.length == 1
96
- if vars[0].downcase == 'settings'
97
- result[vars[0].downcase] = parse_settings(ENV[var])
98
- else
99
- result[vars[0].downcase] = ENV[var]
100
- end
101
- end
102
- end
93
+ result = get_env_vars(var, result) unless ENV[var] == '' || ENV[var].nil?
103
94
  end
104
95
 
96
+ result
97
+ end
98
+
99
+ def load_from_env
100
+ log.debug "will load config from ENV variables"
101
+
102
+ result = make_default_config
103
+ result = env_parser(result)
104
+
105
105
  log.debug "env config: #{result.inspect}"
106
106
  result
107
107
  end
108
108
 
109
- def load_from_argv(argv)
109
+ def load_from_argv
110
110
  require 'optparse'
111
111
 
112
112
  log.debug "will load config from passed arguments"
113
113
  result = make_default_config
114
-
115
114
  result = option_parser(result)
116
115
 
117
116
  if MAIN_PARAMS.map { |p| p.downcase }.map { |key| result[key].empty? }.any?{ |a| a == true }
@@ -2,6 +2,16 @@ require 'logger'
2
2
  require 'colorize'
3
3
 
4
4
  module Logging
5
+
6
+ SEVERITY_COLORS = {
7
+ 'DEBUG' => 'cyan',
8
+ 'INFO' => 'green',
9
+ 'WARN' => 'yellow',
10
+ 'ERROR' => 'light_red',
11
+ 'FATAL' => 'red',
12
+ 'UNKNOWN' => 'magenta'
13
+ }
14
+
5
15
  def log
6
16
  @log ||= Logging.logger_for(self.class.name)
7
17
  end
@@ -15,35 +25,24 @@ module Logging
15
25
  @loggers[classname] ||= configure_logger_for(classname)
16
26
  end
17
27
 
18
- def configure_logger_for(classname)
19
- logger = Logger.new(STDOUT)
20
- logger.progname = classname
21
-
28
+ def log_level
22
29
  # :debug < :info < :warn < :error < :fatal < :unknown
23
30
  if ENV['LOG_LEVEL'] == '' || ENV['LOG_LEVEL'].nil?
24
- logger.level = 'INFO'
31
+ 'INFO'
25
32
  else
26
- logger.level = ENV['LOG_LEVEL']
33
+ ENV['LOG_LEVEL']
27
34
  end
35
+ end
36
+
37
+ def configure_logger_for(classname)
38
+ logger = Logger.new(STDOUT)
39
+ logger.progname = classname
40
+ logger.level = log_level
28
41
 
29
42
  logger.formatter = proc do |severity, datetime, progname, msg|
30
43
  datetime = datetime.strftime("%Y-%m-%d | %I:%M:%S.%L")
31
- message = "#{datetime} | #{progname} | #{severity} | #{msg}\n"
32
-
33
- case severity
34
- when 'DEBUG'
35
- message.cyan
36
- when 'INFO'
37
- message.green
38
- when 'WARN'
39
- message.yellow
40
- when 'ERROR'
41
- message.light_red
42
- when 'FATAL'
43
- message.red
44
- when 'UNKNOWN'
45
- message.magenta
46
- end
44
+ message = "#{datetime} | #{progname} | #{severity} | #{msg}\n"
45
+ message.send(SEVERITY_COLORS[severity])
47
46
  end
48
47
 
49
48
  logger
@@ -0,0 +1,21 @@
1
+ module Open
2
+ def do_open(indices, date)
3
+ indices.each do |index_name|
4
+ next if skip?('open', index_name)
5
+
6
+ index = "#{index_name}-#{date}"
7
+ response = @elastic.request(:get, "/_cat/indices/#{index}")
8
+
9
+ if index_exist?(response)
10
+ next if already?('open', response, index)
11
+
12
+ action_with_log('open', index)
13
+ else
14
+ log.warn "#{index} index not found"
15
+ log.info "#{index} trying snapshot restore"
16
+
17
+ action_with_log('restore_snapshot', index)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -74,16 +74,18 @@ module Request
74
74
  indices.select!{ |_, v| v['state'] == state } if state
75
75
  indices.select!{ |_, v| v['settings']['index']['routing']['allocation']['require']['box_type'] == type } if type
76
76
 
77
- indices.map do |index, _|
77
+ indices.select! do |index, _|
78
78
  begin
79
79
  index_date = Date.parse(index.gsub('-', ''))
80
80
  rescue ArgumentError => e
81
81
  log.error "#{e.message} for #{index}"
82
82
  next
83
83
  end
84
-
85
- URI.escape(index) if (from..to).cover? index_date
84
+ (from..to).cover? index_date
86
85
  end
86
+
87
+ indices = indices.keys.map { |i| i.split('-')[0..-2].join('-') }
88
+ return indices
87
89
  end
88
90
 
89
91
  def get_all_indices
@@ -172,13 +174,13 @@ module Request
172
174
  true
173
175
  end
174
176
 
175
- def open_index(index)
176
- response = request(:post, "/#{index}/_open?master_timeout=1m")
177
+ def index(action, index)
178
+ response = request(:post, "/#{URI.escape(index)}/_#{action}?master_timeout=1m")
177
179
 
178
180
  if response.code == 200
179
181
  response = json_parse(response)
180
182
  else
181
- log.fatal "wrong response code for #{index} open"
183
+ log.fatal "wrong response code for #{index} #{action}"
182
184
  exit 1
183
185
  end
184
186
 
@@ -4,6 +4,11 @@ require 'yajl'
4
4
  module Utils
5
5
  include Logging
6
6
 
7
+ REVERT_STATE = {
8
+ 'open' => 'close',
9
+ 'close' => 'open'
10
+ }
11
+
7
12
  def true?(obj)
8
13
  obj.to_s.downcase == 'true'
9
14
  end
@@ -14,4 +19,87 @@ module Utils
14
19
  log.fatal "json parse err: '''#{e.message}'''\n\t#{e.backtrace.join("\n\t")}"
15
20
  exit 1
16
21
  end
22
+
23
+ def prechecks(date_from, date_to)
24
+ if date_from > date_to
25
+ log.fatal "wrong dates: date to is behind date from. from: #{date_from}, to: #{date_to}"
26
+ exit 1
27
+ end
28
+
29
+ unless true?(@config['force'])
30
+ unless @elastic.green?
31
+ log.fatal "elasticsearch on #{@config['es']['url']} is not green"
32
+ exit 1
33
+ end
34
+ end
35
+ end
36
+
37
+ def prepare_vars
38
+ indices = @config['indices'].split(',')
39
+ date_from = Date.parse(@config['from'])
40
+ date_to = Date.parse(@config['to'])
41
+
42
+ return indices, date_from, date_to
43
+ end
44
+
45
+ def all_precheck(indices, date_from, date_to, state)
46
+ if indices.length == 1 && indices.first == '_all'
47
+ indices = @elastic.all_indices(date_from, date_to, state)
48
+ end
49
+
50
+ indices
51
+ end
52
+
53
+ def action_with_log(action, index)
54
+ if @elastic.index(action, index)
55
+ log.info "#{index} #{action} succes"
56
+ else
57
+ log.error "#{index} #{action} fail"
58
+ end
59
+ end
60
+
61
+ def index_exist?(response)
62
+ if response.code == 200
63
+ return true
64
+ elsif response.code == 404
65
+ return false
66
+ else
67
+ log.fatal "wtf in index_exist? response was: #{response.code} - #{response}"
68
+ exit 1
69
+ end
70
+ end
71
+
72
+ def already?(status, response, index)
73
+ if json_parse(response).first['status'] == status
74
+ log.warn "#{index} index status already #{status}"
75
+ return true
76
+ end
77
+
78
+ false
79
+ end
80
+
81
+ def skip?(status, index_name)
82
+ if @config['settings'][index_name]
83
+ if @config['settings'][index_name]['skip'][status]
84
+ log.debug @config['settings'][index_name]['skip'][status].inspect
85
+
86
+ if true?(@config['settings'][index_name]['skip'][status])
87
+ log.warn "#{index_name} index #{status} skiped"
88
+ return true
89
+ end
90
+ end
91
+ end
92
+
93
+ false
94
+ end
95
+
96
+ def action(task)
97
+ indices, date_from, date_to = prepare_vars
98
+ prechecks(date_from, date_to)
99
+ indices = all_precheck(indices, date_from, date_to, REVERT_STATE[task])
100
+
101
+ date_from.upto(date_to) do |date|
102
+ self.send("do_#{task}", indices, date.to_s.tr!('-', '.'))
103
+ end
104
+ end
17
105
  end
@@ -4,89 +4,28 @@ require 'elastic_manager/config'
4
4
  require 'elastic_manager/logger'
5
5
  require 'elastic_manager/request'
6
6
  require 'elastic_manager/utils'
7
+ require 'elastic_manager/open'
8
+ require 'elastic_manager/close'
7
9
 
8
10
  class ElasticManager
9
11
  include Config
10
12
  include Logging
11
13
  include Request
12
14
  include Utils
13
-
14
- # attr_reader :config
15
+ include Open
16
+ include Close
15
17
 
16
18
  def initialize(argv)
17
19
  if argv.size == 0
18
20
  @config = load_from_env
19
21
  else
20
- @config = load_from_argv(argv)
22
+ @config = load_from_argv
21
23
  end
22
24
 
23
25
  @elastic = Request::Elastic.new(@config)
24
26
  end
25
27
 
26
- def work
27
- if @config['task'].downcase == 'open'
28
- indices = @config['indices'].split(',')
29
- date_from = Date.parse(@config['from'])
30
- date_to = Date.parse(@config['to'])
31
-
32
- unless true?(@config['force'])
33
- unless @elastic.green?
34
- log.fatal "elasticsearch on #{@config['es']['url']} is not green"
35
- exit 1
36
- end
37
- end
38
-
39
- if indices.length == 1 && indices.first == '_all'
40
- # indices = es_all_indices(date_from, date_to, 'close')
41
- indices = @elastic.all_indices(date_from, date_to, 'close')
42
- end
43
-
44
- date_from.upto(date_to) do |date|
45
- date = date.to_s.tr!('-', '.')
46
-
47
- indices.each do |index_name|
48
- if @config['settings'][index_name]
49
- if @config['settings'][index_name]['skip_open']
50
- log.debug @config['settings'][index_name]['skip_open'].inspect
51
-
52
- if true?(@config['settings'][index_name]['skip_open'])
53
- log.warn "#{index_name} index open skiped"
54
- next
55
- end
56
- end
57
- end
58
-
59
- index = "#{index_name}-#{date}"
60
-
61
- response = @elastic.request(:get, "/_cat/indices/#{index}")
62
-
63
- if response.code == 404
64
- log.warn "#{index} index not found"
65
- log.info "#{index} trying snapshot restore"
66
-
67
- if @elastic.restore_snapshot(index)
68
- log.info "#{index} restored"
69
- else
70
- log.error "#{index} troubles with restore"
71
- end
72
- elsif response.code == 200
73
- if response.body.to_s =~ /open/
74
- log.warn "#{index} index already opened"
75
- next
76
- end
77
-
78
- if @elastic.open_index(index)
79
- log.info "#{index} index open success"
80
- else
81
- log.fatal "#{index} index open failed"
82
- exit 1
83
- end
84
- else
85
- log.fatal "can't work with index #{index} response was: #{response.code} - #{response}"
86
- exit 1
87
- end
88
- end
89
- end
90
- end
28
+ def run
29
+ action(@config['task'].downcase)
91
30
  end
92
31
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elastic_manager
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Antony Ryabov
@@ -94,8 +94,10 @@ files:
94
94
  - bin/elastic_manager
95
95
  - elastic_manager.gemspec
96
96
  - lib/elastic_manager.rb
97
+ - lib/elastic_manager/close.rb
97
98
  - lib/elastic_manager/config.rb
98
99
  - lib/elastic_manager/logger.rb
100
+ - lib/elastic_manager/open.rb
99
101
  - lib/elastic_manager/request.rb
100
102
  - lib/elastic_manager/utils.rb
101
103
  homepage: https://github.com/onetwotrip/elastic_manager