~cytrogen/masto-fe

ref: 85db3924645ebd20f0259356fa7556a2e8055b36 masto-fe/app/lib/admin/system_check/elasticsearch_check.rb -rw-r--r-- 3.3 KiB
85db3924 — Nick Schonning Autofix Rubocop cops for config/ (#24145) 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# frozen_string_literal: true

class Admin::SystemCheck::ElasticsearchCheck < Admin::SystemCheck::BaseCheck
  INDEXES = [
    InstancesIndex,
    AccountsIndex,
    TagsIndex,
    StatusesIndex,
    PublicStatusesIndex,
  ].freeze

  def skip?
    !current_user.can?(:view_devops)
  end

  def pass?
    return true unless Chewy.enabled?

    running_version.present? && compatible_version? && cluster_health['status'] == 'green' && indexes_match? && preset_matches?
  rescue Faraday::ConnectionFailed, Elasticsearch::Transport::Transport::Error
    false
  end

  def message
    if running_version.blank?
      Admin::SystemCheck::Message.new(:elasticsearch_running_check)
    elsif !compatible_version?
      Admin::SystemCheck::Message.new(
        :elasticsearch_version_check,
        I18n.t(
          'admin.system_checks.elasticsearch_version_check.version_comparison',
          running_version: running_version,
          required_version: required_version
        )
      )
    elsif !indexes_match?
      Admin::SystemCheck::Message.new(
        :elasticsearch_index_mismatch,
        mismatched_indexes.join(' ')
      )
    elsif cluster_health['status'] == 'red'
      Admin::SystemCheck::Message.new(:elasticsearch_health_red)
    elsif cluster_health['number_of_nodes'] < 2 && es_preset != 'single_node_cluster'
      Admin::SystemCheck::Message.new(:elasticsearch_preset_single_node, nil, 'https://docs.joinmastodon.org/admin/elasticsearch/#scaling')
    elsif Chewy.client.indices.get_settings[Chewy::Stash::Specification.index_name]&.dig('settings', 'index', 'number_of_replicas')&.to_i&.positive? && es_preset == 'single_node_cluster'
      Admin::SystemCheck::Message.new(:elasticsearch_reset_chewy)
    elsif cluster_health['status'] == 'yellow'
      Admin::SystemCheck::Message.new(:elasticsearch_health_yellow)
    else
      Admin::SystemCheck::Message.new(:elasticsearch_preset, nil, 'https://docs.joinmastodon.org/admin/elasticsearch/#scaling')
    end
  rescue Faraday::ConnectionFailed, Elasticsearch::Transport::Transport::Error
    Admin::SystemCheck::Message.new(:elasticsearch_running_check)
  end

  private

  def cluster_health
    @cluster_health ||= Chewy.client.cluster.health
  end

  def running_version
    @running_version ||= begin
      Chewy.client.info['version']['number']
    rescue Faraday::ConnectionFailed, Elasticsearch::Transport::Transport::Error
      nil
    end
  end

  def compatible_wire_version
    Chewy.client.info['version']['minimum_wire_compatibility_version']
  end

  def required_version
    '7.x'
  end

  def compatible_version?
    return false if running_version.nil?

    Gem::Version.new(running_version) >= Gem::Version.new(required_version) ||
      Gem::Version.new(compatible_wire_version) >= Gem::Version.new(required_version)
  rescue ArgumentError
    false
  end

  def mismatched_indexes
    @mismatched_indexes ||= INDEXES.filter_map do |klass|
      klass.base_name if Chewy.client.indices.get_mapping[klass.index_name]&.deep_symbolize_keys != klass.mappings_hash
    end
  end

  def indexes_match?
    mismatched_indexes.empty?
  end

  def es_preset
    ENV.fetch('ES_PRESET', 'single_node_cluster')
  end

  def preset_matches?
    case es_preset
    when 'single_node_cluster'
      cluster_health['number_of_nodes'] == 1
    else
      cluster_health['number_of_nodes'] > 1
    end
  end
end