check_mk_controller.rb 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. # Copyright (C) 2012-2023 Zammad Foundation, https://zammad-foundation.org/
  2. class Integration::CheckMkController < ApplicationController
  3. skip_before_action :verify_csrf_token
  4. before_action :check_configured
  5. def update
  6. # check params
  7. raise Exceptions::UnprocessableEntity, 'event_id is missing!' if params[:event_id].blank?
  8. raise Exceptions::UnprocessableEntity, 'state is missing!' if params[:state].blank?
  9. raise Exceptions::UnprocessableEntity, 'host is missing!' if params[:host].blank?
  10. # search for open ticket
  11. auto_close = Setting.get('check_mk_auto_close')
  12. auto_close_state_id = Setting.get('check_mk_auto_close_state_id')
  13. group_id = Setting.get('check_mk_group_id')
  14. state_recovery_match = '(OK|UP)'
  15. # follow-up detection by meta data
  16. integration = 'check_mk'
  17. open_states = Ticket::State.by_category(:open)
  18. ticket_ids = Ticket.where(state: open_states).order(created_at: :desc).limit(5000).pluck(:id)
  19. ticket_ids_found = []
  20. ticket_ids.each do |ticket_id|
  21. ticket = Ticket.find_by(id: ticket_id)
  22. next if !ticket
  23. next if !ticket.preferences
  24. next if !ticket.preferences[integration]
  25. next if !ticket.preferences[integration]['host']
  26. next if ticket.preferences[integration]['host'] != params[:host]
  27. next if ticket.preferences[integration]['service'] != params[:service]
  28. # found open ticket for service+host
  29. ticket_ids_found.push ticket.id
  30. end
  31. # new ticket, set meta data
  32. title = "#{params[:host]} is #{params[:state]}"
  33. body = "EventID: #{params[:event_id]}
  34. Host: #{params[:host]}
  35. Service: #{params[:service] || '-'}
  36. State: #{params[:state]}
  37. Text: #{params[:text] || '-'}
  38. RemoteIP: #{request.remote_ip}
  39. UserAgent: #{request.env['HTTP_USER_AGENT'] || '-'}
  40. "
  41. # add article
  42. if params[:state].present? && ticket_ids_found.present?
  43. ticket_ids_found.each do |ticket_id|
  44. ticket = Ticket.find_by(id: ticket_id)
  45. next if !ticket
  46. Ticket::Article.create!(
  47. ticket_id: ticket_id,
  48. type_id: Ticket::Article::Type.find_by(name: 'web').id,
  49. sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id,
  50. body: body,
  51. subject: title,
  52. internal: false,
  53. )
  54. end
  55. if (!auto_close && params[:state].match(%r{#{state_recovery_match}}i)) || !params[:state].match(%r{#{state_recovery_match}}i)
  56. render json: {
  57. result: 'ticket already open, added note',
  58. ticket_ids: ticket_ids_found,
  59. }
  60. return
  61. end
  62. end
  63. # check if service is recovered
  64. if auto_close && params[:state].present? && params[:state].match(%r{#{state_recovery_match}}i)
  65. if ticket_ids_found.blank?
  66. render json: {
  67. result: 'no open tickets found, ignore action',
  68. }
  69. return
  70. end
  71. ticket_ids_found.each do |ticket_id|
  72. ticket = Ticket.find_by(id: ticket_id)
  73. next if !ticket
  74. ticket.state_id = auto_close_state_id
  75. ticket.save!
  76. end
  77. render json: {
  78. result: "closed tickets with ids #{ticket_ids_found.join(',')}",
  79. ticket_ids: ticket_ids_found,
  80. }
  81. return
  82. end
  83. # define customer of ticket
  84. customer = nil
  85. if params[:customer].present?
  86. customer = User.find_by(login: params[:customer].downcase)
  87. if !customer
  88. customer = User.find_by(email: params[:customer].downcase)
  89. end
  90. end
  91. if !customer
  92. customer = User.lookup(id: 1)
  93. end
  94. params[:state] = nil
  95. params[:customer] = nil
  96. ticket = Ticket.new(Ticket.param_cleanup(Ticket.association_name_to_id_convert(params)))
  97. ticket.group_id ||= group_id
  98. ticket.customer_id = customer.id
  99. ticket.title = title
  100. ticket.preferences = {
  101. check_mk: {
  102. host: params[:host],
  103. service: params[:service],
  104. },
  105. }
  106. ticket.save!
  107. Ticket::Article.create!(
  108. ticket_id: ticket.id,
  109. type_id: Ticket::Article::Type.find_by(name: 'web').id,
  110. sender_id: Ticket::Article::Sender.find_by(name: 'Customer').id,
  111. body: body,
  112. subject: title,
  113. internal: false,
  114. )
  115. render json: {
  116. result: "new ticket created (ticket id: #{ticket.id})",
  117. ticket_id: ticket.id,
  118. ticket_number: ticket.number,
  119. }
  120. end
  121. private
  122. def check_configured
  123. http_log_config facility: 'check_mk'
  124. if !Setting.get('check_mk_integration')
  125. raise Exceptions::UnprocessableEntity, __('Feature is disabled, please contact your administrator!')
  126. end
  127. if Setting.get('check_mk_token') != params[:token]
  128. raise Exceptions::UnprocessableEntity, __('The provided token is invalid.')
  129. end
  130. true
  131. end
  132. end