You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

state.rb 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. module CryptCheck
  2. module State
  3. def states
  4. # Remove duplicated test for each level
  5. @states ||= self.checks.group_by { |c| c[1] }.collect do |level, checks|
  6. states = checks.group_by(&:first).collect do |name, checks|
  7. states = checks.collect &:last
  8. # true > false > nil
  9. state = if states.include? true
  10. true
  11. elsif states.include? false
  12. false
  13. else
  14. nil
  15. end
  16. [name, state]
  17. end.to_h
  18. [level, states]
  19. end.to_h
  20. end
  21. def status
  22. @status ||= State.status self.checks.select { |c| c.last == true }.collect { |c| c[1] }
  23. end
  24. BADS = %i(critical error warning).freeze
  25. GOODS = %i(good great best).freeze
  26. LEVELS = (BADS + GOODS).freeze
  27. extend Enumerable
  28. def self.each(&block)
  29. LEVELS.each &block
  30. end
  31. def self.empty
  32. self.collect { |s| [s, []] }.to_h
  33. end
  34. def self.status(states)
  35. states = self.convert states
  36. self.min LEVELS, states
  37. end
  38. class << self
  39. alias_method :'[]', :status
  40. end
  41. def self.problem(states)
  42. states = self.convert states
  43. self.min BADS, states
  44. end
  45. def self.sort(states)
  46. states.sort { |a, b| self.compare a, b }
  47. end
  48. def self.compare(a, b)
  49. a = LEVELS.find_index(a.status) || (LEVELS.size - 1) / 2.0
  50. b = LEVELS.find_index(b.status) || (LEVELS.size - 1) / 2.0
  51. a <=> b
  52. end
  53. protected
  54. def checks
  55. @checks ||= self.available_checks.collect { |c| perform_check c }.flatten(1) + children.collect(&:checks).flatten(1)
  56. end
  57. private
  58. def self.convert(status)
  59. status = [status] unless status.respond_to? :first
  60. first = status.first
  61. status = status.collect &:status if first.respond_to? :status
  62. status
  63. end
  64. def self.min(levels, states)
  65. return nil if states.empty?
  66. (levels & states).first
  67. end
  68. def self.max(levels, states)
  69. return nil if states.empty?
  70. (levels & states).last
  71. end
  72. def self.merge(*states)
  73. State.collect do |s|
  74. state = states.collect { |ss| ss.fetch s, [] }
  75. .inject(&:+).uniq
  76. [s, state]
  77. end.to_h
  78. end
  79. def children
  80. []
  81. end
  82. def perform_check(check)
  83. name, levels, check = check
  84. result = check.call self
  85. case levels
  86. when Symbol # Expected result is true/false/nil
  87. return [[name, levels, result]]
  88. else # Expected result is the best/worst case
  89. # N/A, so return all levels as N/A
  90. return levels.collect { |l| [name, l, nil] } if result.nil?
  91. checks = []
  92. if BADS.include? result
  93. checks += (GOODS & levels).collect { |l| [name, l, false] }
  94. index = BADS.index result
  95. checks += (BADS & levels).collect { |l| [name, l, BADS.index(l) >= index] }
  96. else
  97. checks += (BADS & levels).collect { |l| [name, l, false] }
  98. index = GOODS.index result
  99. checks += (GOODS & levels).collect { |l| [name, l, GOODS.index(l) <= index] }
  100. end
  101. return checks
  102. end
  103. end
  104. end
  105. end