elasticsearch_check.rb 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. # frozen_string_literal: true
  2. class Admin::SystemCheck::ElasticsearchCheck < Admin::SystemCheck::BaseCheck
  3. INDEXES = [
  4. InstancesIndex,
  5. AccountsIndex,
  6. TagsIndex,
  7. StatusesIndex,
  8. ].freeze
  9. def skip?
  10. !current_user.can?(:view_devops)
  11. end
  12. def pass?
  13. return true unless Chewy.enabled?
  14. running_version.present? && compatible_version? && cluster_health['status'] == 'green' && indexes_match? && preset_matches?
  15. rescue Faraday::ConnectionFailed, Elasticsearch::Transport::Transport::Error
  16. false
  17. end
  18. def message
  19. if running_version.blank?
  20. Admin::SystemCheck::Message.new(:elasticsearch_running_check)
  21. elsif !compatible_version?
  22. Admin::SystemCheck::Message.new(
  23. :elasticsearch_version_check,
  24. I18n.t(
  25. 'admin.system_checks.elasticsearch_version_check.version_comparison',
  26. running_version: running_version,
  27. required_version: required_version
  28. )
  29. )
  30. elsif !indexes_match?
  31. Admin::SystemCheck::Message.new(
  32. :elasticsearch_index_mismatch,
  33. mismatched_indexes.join(' ')
  34. )
  35. elsif cluster_health['status'] == 'red'
  36. Admin::SystemCheck::Message.new(:elasticsearch_health_red)
  37. elsif cluster_health['number_of_nodes'] < 2 && es_preset != 'single_node_cluster'
  38. Admin::SystemCheck::Message.new(:elasticsearch_preset_single_node, nil, 'https://docs.joinmastodon.org/admin/optional/elasticsearch/#scaling')
  39. elsif Chewy.client.indices.get_settings['chewy_specifications'].dig('settings', 'index', 'number_of_replicas')&.to_i&.positive? && es_preset == 'single_node_cluster'
  40. Admin::SystemCheck::Message.new(:elasticsearch_reset_chewy)
  41. elsif cluster_health['status'] == 'yellow'
  42. Admin::SystemCheck::Message.new(:elasticsearch_health_yellow)
  43. else
  44. Admin::SystemCheck::Message.new(:elasticsearch_preset, nil, 'https://docs.joinmastodon.org/admin/optional/elasticsearch/#scaling')
  45. end
  46. rescue Faraday::ConnectionFailed, Elasticsearch::Transport::Transport::Error
  47. Admin::SystemCheck::Message.new(:elasticsearch_running_check)
  48. end
  49. private
  50. def cluster_health
  51. @cluster_health ||= Chewy.client.cluster.health
  52. end
  53. def running_version
  54. @running_version ||= begin
  55. Chewy.client.info['version']['number']
  56. rescue Faraday::ConnectionFailed, Elasticsearch::Transport::Transport::Error
  57. nil
  58. end
  59. end
  60. def compatible_wire_version
  61. Chewy.client.info['version']['minimum_wire_compatibility_version']
  62. end
  63. def required_version
  64. '7.x'
  65. end
  66. def compatible_version?
  67. return false if running_version.nil?
  68. Gem::Version.new(running_version) >= Gem::Version.new(required_version) ||
  69. Gem::Version.new(compatible_wire_version) >= Gem::Version.new(required_version)
  70. rescue ArgumentError
  71. false
  72. end
  73. def mismatched_indexes
  74. @mismatched_indexes ||= INDEXES.filter_map do |klass|
  75. klass.index_name if Chewy.client.indices.get_mapping[klass.index_name]&.deep_symbolize_keys != klass.mappings_hash
  76. end
  77. end
  78. def indexes_match?
  79. mismatched_indexes.empty?
  80. end
  81. def es_preset
  82. ENV.fetch('ES_PRESET', 'single_node_cluster')
  83. end
  84. def preset_matches?
  85. case es_preset
  86. when 'single_node_cluster'
  87. cluster_health['number_of_nodes'] == 1
  88. else
  89. cluster_health['number_of_nodes'] > 1
  90. end
  91. end
  92. end