Added icinga integration.
This commit is contained in:
parent
1fd36cfc6a
commit
f48e742d23
12 changed files with 692 additions and 74 deletions
|
@ -0,0 +1,12 @@
|
|||
class Icinga extends App.ControllerTabs
|
||||
header: 'Icinga'
|
||||
constructor: ->
|
||||
super
|
||||
return if !@authenticate(false, 'Admin')
|
||||
@title 'Icinga', true
|
||||
@tabs = [
|
||||
{ name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Integration::Icinga' } }
|
||||
]
|
||||
@render()
|
||||
|
||||
App.Config.set('IntegrationIcinga', { prio: 1100, parent: '#integration', name: 'Icinga', target: '#integration/icinga', controller: Icinga, role: ['Admin'] }, 'NavBarIntegration')
|
|
@ -0,0 +1,12 @@
|
|||
class Mattermost extends App.ControllerTabs
|
||||
header: 'Mattermost'
|
||||
constructor: ->
|
||||
super
|
||||
return if !@authenticate(false, 'Admin')
|
||||
@title 'Mattermost', true
|
||||
@tabs = [
|
||||
{ name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Integration::Mattermost' } }
|
||||
]
|
||||
@render()
|
||||
|
||||
App.Config.set('IntegrationMattermost', { prio: 1000, parent: '#integration', name: 'Mattermost', target: '#integration/mattermost', controller: Mattermost, role: ['Admin'] }, 'NavBarIntegration')
|
|
@ -0,0 +1,12 @@
|
|||
class Nagios extends App.ControllerTabs
|
||||
header: 'Nagios'
|
||||
constructor: ->
|
||||
super
|
||||
return if !@authenticate(false, 'Admin')
|
||||
@title 'Nagios', true
|
||||
@tabs = [
|
||||
{ name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Integration::Nagios' } }
|
||||
]
|
||||
@render()
|
||||
|
||||
App.Config.set('IntegrationNagios', { prio: 1200, parent: '#integration', name: 'Nagios', target: '#integration/nagios', controller: Nagios, role: ['Admin'] }, 'NavBarIntegration')
|
|
@ -0,0 +1,8 @@
|
|||
class IndexRouter extends App.ControllerNavSidbar
|
||||
authenticateRequired: true
|
||||
configKey: 'NavBarIntegration'
|
||||
|
||||
App.Config.set('integration', IndexRouter, 'Routes')
|
||||
App.Config.set('integration/:target', IndexRouter, 'Routes')
|
||||
|
||||
App.Config.set('Integration', { prio: 1000, name: 'Integration', target: '#integration', role: ['Admin'] }, 'NavBarIntegration')
|
|
@ -62,9 +62,8 @@ class Ticket extends App.ControllerTabs
|
|||
]
|
||||
@render()
|
||||
|
||||
App.Config.set( 'SettingBranding', { prio: 1200, parent: '#settings', name: 'Branding', target: '#settings/branding', controller: Branding, role: ['Admin'] }, 'NavBarAdmin' )
|
||||
App.Config.set( 'SettingSystem', { prio: 1400, parent: '#settings', name: 'System', target: '#settings/system', controller: System, role: ['Admin'] }, 'NavBarAdmin' )
|
||||
App.Config.set( 'SettingSecurity', { prio: 1600, parent: '#settings', name: 'Security', target: '#settings/security', controller: Security, role: ['Admin'] }, 'NavBarAdmin' )
|
||||
App.Config.set( 'SettingTicket', { prio: 1700, parent: '#settings', name: 'Ticket', target: '#settings/ticket', controller: Ticket, role: ['Admin'] }, 'NavBarAdmin' )
|
||||
App.Config.set( 'SettingImport', { prio: 1800, parent: '#settings', name: 'Import', target: '#settings/import', controller: Import, role: ['Admin'] }, 'NavBarAdmin' )
|
||||
|
||||
App.Config.set('SettingBranding', { prio: 1200, parent: '#settings', name: 'Branding', target: '#settings/branding', controller: Branding, role: ['Admin'] }, 'NavBarAdmin')
|
||||
App.Config.set('SettingSystem', { prio: 1400, parent: '#settings', name: 'System', target: '#settings/system', controller: System, role: ['Admin'] }, 'NavBarAdmin')
|
||||
App.Config.set('SettingSecurity', { prio: 1600, parent: '#settings', name: 'Security', target: '#settings/security', controller: Security, role: ['Admin'] }, 'NavBarAdmin')
|
||||
App.Config.set('SettingTicket', { prio: 1700, parent: '#settings', name: 'Ticket', target: '#settings/ticket', controller: Ticket, role: ['Admin'] }, 'NavBarAdmin')
|
||||
App.Config.set('SettingImport', { prio: 1800, parent: '#settings', name: 'Import', target: '#settings/import', controller: Import, role: ['Admin'] }, 'NavBarAdmin')
|
||||
|
|
|
@ -43,12 +43,18 @@ class Channel::EmailParser
|
|||
x-zammad-customer-firstname: '',
|
||||
x-zammad-customer-lastname: '',
|
||||
|
||||
# ticket headers
|
||||
# ticket headers (for new tickets)
|
||||
x-zammad-ticket-group: 'some_group',
|
||||
x-zammad-ticket-state: 'some_state',
|
||||
x-zammad-ticket-priority: 'some_priority',
|
||||
x-zammad-ticket-owner: 'some_owner_login',
|
||||
|
||||
# ticket headers (for existing tickets)
|
||||
x-zammad-ticket-followup-group: 'some_group',
|
||||
x-zammad-ticket-followup-state: 'some_state',
|
||||
x-zammad-ticket-followup-priority: 'some_priority',
|
||||
x-zammad-ticket-followup-owner: 'some_owner_login',
|
||||
|
||||
# article headers
|
||||
x-zammad-article-internal: false,
|
||||
x-zammad-article-type: 'agent',
|
||||
|
@ -66,7 +72,6 @@ class Channel::EmailParser
|
|||
|
||||
# set all headers
|
||||
mail.header.fields.each { |field|
|
||||
|
||||
next if !field.name
|
||||
|
||||
# full line, encode, ready for storage
|
||||
|
@ -79,20 +84,15 @@ class Channel::EmailParser
|
|||
# get sender
|
||||
from = nil
|
||||
['from', 'reply-to', 'return-path'].each { |item|
|
||||
|
||||
next if !mail[ item.to_sym ]
|
||||
|
||||
from = mail[ item.to_sym ].value
|
||||
|
||||
break if from
|
||||
}
|
||||
|
||||
# set x-any-recipient
|
||||
data['x-any-recipient'.to_sym] = ''
|
||||
['to', 'cc', 'delivered-to', 'x-original-to', 'envelope-to'].each { |item|
|
||||
|
||||
next if !mail[item.to_sym]
|
||||
|
||||
if data['x-any-recipient'.to_sym] != ''
|
||||
data['x-any-recipient'.to_sym] += ', '
|
||||
end
|
||||
|
@ -347,7 +347,7 @@ retrns
|
|||
|
||||
# run postmaster pre filter
|
||||
filters = {}
|
||||
Setting.where(area: 'Postmaster::PreFilter').each {|setting|
|
||||
Setting.where(area: 'Postmaster::PreFilter').order(:name).each {|setting|
|
||||
filters[setting.name] = Kernel.const_get(Setting.get(setting.name))
|
||||
}
|
||||
filters.each {|_prio, backend|
|
||||
|
@ -373,35 +373,15 @@ retrns
|
|||
# reset current_user
|
||||
UserInfo.current_user_id = 1
|
||||
|
||||
# create sender
|
||||
if mail[ 'x-zammad-customer-login'.to_sym ]
|
||||
user = User.find_by(login: mail[ 'x-zammad-customer-login'.to_sym ])
|
||||
# create sender if needed
|
||||
sender_user_id = mail[ 'x-zammad-customer-id'.to_sym ]
|
||||
if !sender_user_id
|
||||
raise 'No x-zammad-customer-id, no sender set!'
|
||||
end
|
||||
user = User.lookup(id: sender_user_id)
|
||||
if !user
|
||||
user = User.find_by(email: mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email])
|
||||
raise "No user found for x-zammad-customer-id: #{sender_user_id}!"
|
||||
end
|
||||
if !user
|
||||
user = user_create(
|
||||
login: mail[ 'x-zammad-customer-login'.to_sym ] || mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
|
||||
firstname: mail[ 'x-zammad-customer-firstname'.to_sym ] || mail[:from_display_name],
|
||||
lastname: mail[ 'x-zammad-customer-lastname'.to_sym ],
|
||||
email: mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
|
||||
)
|
||||
end
|
||||
|
||||
# create to and cc user
|
||||
['raw-to', 'raw-cc'].each { |item|
|
||||
next if !mail[item.to_sym]
|
||||
next if !mail[item.to_sym].addrs
|
||||
items = mail[item.to_sym].addrs
|
||||
items.each {|address_data|
|
||||
user_create(
|
||||
firstname: address_data.display_name,
|
||||
lastname: '',
|
||||
email: address_data.address,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
# set current user
|
||||
UserInfo.current_user_id = user.id
|
||||
|
@ -416,6 +396,8 @@ retrns
|
|||
|
||||
# set ticket state to open if not new
|
||||
if ticket
|
||||
set_attributes_by_x_headers(ticket, 'ticket', mail, 'followup')
|
||||
|
||||
state = Ticket::State.find(ticket.state_id)
|
||||
state_type = Ticket::StateType.find(state.state_type_id)
|
||||
|
||||
|
@ -425,9 +407,11 @@ retrns
|
|||
end
|
||||
|
||||
# set ticket to open again
|
||||
if state_type.name != 'new' && !mail[ 'x-zammad-out-of-office'.to_sym ]
|
||||
ticket.state = Ticket::State.find_by(name: 'open')
|
||||
ticket.save
|
||||
if !mail[ 'x-zammad-ticket-followup-state'.to_sym ]
|
||||
if state_type.name != 'new' && !mail[ 'x-zammad-out-of-office'.to_sym ]
|
||||
ticket.state = Ticket::State.find_by(name: 'open')
|
||||
ticket.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -505,7 +489,7 @@ retrns
|
|||
Observer::Ticket::Notification.transaction
|
||||
|
||||
# run postmaster post filter
|
||||
Setting.where(area: 'Postmaster::PostFilter').each {|setting|
|
||||
Setting.where(area: 'Postmaster::PostFilter').order(:name).each {|setting|
|
||||
filters[setting.name] = Kernel.const_get(Setting.get(setting.name))
|
||||
}
|
||||
filters.each {|_prio, backend|
|
||||
|
@ -521,36 +505,7 @@ retrns
|
|||
[ticket, article, user, mail]
|
||||
end
|
||||
|
||||
def user_create(data)
|
||||
|
||||
# return existing
|
||||
user = User.find_by(login: data[:email].downcase)
|
||||
return user if user
|
||||
|
||||
# create new user
|
||||
roles = Role.where(name: 'Customer')
|
||||
|
||||
# fillup
|
||||
%w(firstname lastname).each { |item|
|
||||
if data[item.to_sym].nil?
|
||||
data[item.to_sym] = ''
|
||||
end
|
||||
}
|
||||
data[:password] = ''
|
||||
data[:active] = true
|
||||
data[:roles] = roles
|
||||
data[:updated_by_id] = 1
|
||||
data[:created_by_id] = 1
|
||||
|
||||
user = User.create(data)
|
||||
user.update_attributes(
|
||||
updated_by_id: user.id,
|
||||
created_by_id: user.id,
|
||||
)
|
||||
user
|
||||
end
|
||||
|
||||
def set_attributes_by_x_headers(item_object, header_name, mail)
|
||||
def set_attributes_by_x_headers(item_object, header_name, mail, suffix = false)
|
||||
|
||||
# loop all x-zammad-hedaer-* headers
|
||||
item_object.attributes.each {|key, _value|
|
||||
|
@ -566,6 +521,9 @@ retrns
|
|||
if key_short == '_id'
|
||||
key_short = key[ 0, key.length - 3 ]
|
||||
header = "x-zammad-#{header_name}-#{key_short}"
|
||||
if suffix
|
||||
header = "x-zammad-#{header_name}-#{suffix}-#{key_short}"
|
||||
end
|
||||
if mail[ header.to_sym ]
|
||||
Rails.logger.info "header #{header} found #{mail[ header.to_sym ]}"
|
||||
item_object.class.reflect_on_all_associations.map { |assoc|
|
||||
|
|
77
app/models/channel/filter/icinga.rb
Normal file
77
app/models/channel/filter/icinga.rb
Normal file
|
@ -0,0 +1,77 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
module Channel::Filter::Icinga
|
||||
|
||||
def self.run(_channel, mail)
|
||||
return if !Setting.get('ichinga_integration')
|
||||
|
||||
# set config
|
||||
integration = 'ichinga'
|
||||
sender = Setting.get('ichinga_sender')
|
||||
auto_close = Setting.get('ichinga_auto_close')
|
||||
auto_close_state_id = Setting.get('ichinga_auto_close_state_id')
|
||||
state_recovery_match = 'OK'
|
||||
|
||||
return if !mail[:from]
|
||||
return if !mail[:body]
|
||||
sender_user_id = mail[ 'x-zammad-customer-id'.to_sym ]
|
||||
return if !sender_user_id
|
||||
|
||||
# check if sender is ichinga
|
||||
return if !mail[:from].match(/#{sender}/i)
|
||||
|
||||
# get mail attibutes like host and state
|
||||
result = {}
|
||||
mail[:body].gsub(%r{(Service|Host|State|Address|Date/Time|Additional\sInfo):(.+?)\n}i) { |_match|
|
||||
key = $1
|
||||
if key
|
||||
key = key.downcase
|
||||
end
|
||||
value = $2
|
||||
if value
|
||||
value.strip!
|
||||
end
|
||||
result[key] = value
|
||||
}
|
||||
|
||||
# check if ticket with host is open
|
||||
customer = User.lookup(id: sender_user_id)
|
||||
|
||||
# follow up detection by meta data
|
||||
open_states = Ticket::State.by_category('open')
|
||||
Ticket.where(state: open_states).each {|ticket|
|
||||
next if !ticket.preferences
|
||||
next if !ticket.preferences['integration']
|
||||
next if ticket.preferences['integration'] != integration
|
||||
next if !ticket.preferences['ichinga']
|
||||
next if !ticket.preferences['ichinga']['host']
|
||||
next if ticket.preferences['ichinga']['host'] != result['host']
|
||||
next if ticket.preferences['ichinga']['service'] != result['service']
|
||||
|
||||
# found open ticket for service+host
|
||||
mail[ 'x-zammad-ticket-id'.to_sym ] = ticket.id
|
||||
|
||||
# check if service is recovered
|
||||
if auto_close && result['state'].match(/#{state_recovery_match}/i)
|
||||
state = Ticket::State.lookup(id: auto_close_state_id)
|
||||
if state
|
||||
mail[ 'x-zammad-ticket-followup-state'.to_sym ] = state.name
|
||||
end
|
||||
end
|
||||
return true
|
||||
}
|
||||
|
||||
# new ticket, set meta data
|
||||
if !mail[ 'x-zammad-ticket-id'.to_sym ]
|
||||
if !mail[ 'x-zammad-ticket-preferences'.to_sym ]
|
||||
mail[ 'x-zammad-ticket-preferences'.to_sym ] = {}
|
||||
end
|
||||
preferences = {}
|
||||
preferences['integration'] = integration
|
||||
preferences['ichinga'] = result
|
||||
preferences.each {|key, value|
|
||||
mail[ 'x-zammad-ticket-preferences'.to_sym ][key] = value
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
88
app/models/channel/filter/identify_sender.rb
Normal file
88
app/models/channel/filter/identify_sender.rb
Normal file
|
@ -0,0 +1,88 @@
|
|||
# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
module Channel::Filter::IdentifySender
|
||||
|
||||
def self.run(_channel, mail)
|
||||
|
||||
user_id = mail[ 'x-zammad-customer-id'.to_sym ]
|
||||
user = nil
|
||||
if user_id
|
||||
user = User.lookup(id: user_id)
|
||||
if !user
|
||||
Rails.logger.debug "Invalid x-zammad-customer-id header '#{user_id}', no such user."
|
||||
else
|
||||
Rails.logger.debug "Took customer form x-zammad-customer-id header '#{user_id}'."
|
||||
if user
|
||||
create_recipients(mail)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# check if sender exists in database
|
||||
if mail[ 'x-zammad-customer-login'.to_sym ]
|
||||
user = User.find_by(login: mail[ 'x-zammad-customer-login'.to_sym ])
|
||||
end
|
||||
if !user
|
||||
user = User.find_by(email: mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email])
|
||||
end
|
||||
if !user
|
||||
user = user_create(
|
||||
login: mail[ 'x-zammad-customer-login'.to_sym ] || mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
|
||||
firstname: mail[ 'x-zammad-customer-firstname'.to_sym ] || mail[:from_display_name],
|
||||
lastname: mail[ 'x-zammad-customer-lastname'.to_sym ],
|
||||
email: mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
|
||||
)
|
||||
end
|
||||
|
||||
create_recipients(mail)
|
||||
|
||||
mail[ 'x-zammad-customer-id'.to_sym ] = user.id
|
||||
end
|
||||
|
||||
# create to and cc user
|
||||
def self.create_recipients(mail)
|
||||
['raw-to', 'raw-cc'].each { |item|
|
||||
next if !mail[item.to_sym]
|
||||
next if !mail[item.to_sym].addrs
|
||||
items = mail[item.to_sym].addrs
|
||||
items.each {|address_data|
|
||||
user_create(
|
||||
firstname: address_data.display_name,
|
||||
lastname: '',
|
||||
email: address_data.address,
|
||||
)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def self.user_create(data)
|
||||
|
||||
# return existing
|
||||
user = User.find_by(login: data[:email].downcase)
|
||||
return user if user
|
||||
|
||||
# create new user
|
||||
roles = Role.where(name: 'Customer')
|
||||
|
||||
# fillup
|
||||
%w(firstname lastname).each { |item|
|
||||
if data[item.to_sym].nil?
|
||||
data[item.to_sym] = ''
|
||||
end
|
||||
}
|
||||
data[:password] = ''
|
||||
data[:active] = true
|
||||
data[:roles] = roles
|
||||
data[:updated_by_id] = 1
|
||||
data[:created_by_id] = 1
|
||||
|
||||
user = User.create(data)
|
||||
user.update_attributes(
|
||||
updated_by_id: user.id,
|
||||
created_by_id: user.id,
|
||||
)
|
||||
user
|
||||
end
|
||||
|
||||
end
|
152
db/migrate/20160412000002_add_ichinga_integration.rb
Normal file
152
db/migrate/20160412000002_add_ichinga_integration.rb
Normal file
|
@ -0,0 +1,152 @@
|
|||
class AddIchingaIntegration < ActiveRecord::Migration
|
||||
def up
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Define postmaster filter.',
|
||||
name: '0015_postmaster_filter_identify_sender',
|
||||
area: 'Postmaster::PreFilter',
|
||||
description: 'Define postmaster filter to identify sender user.',
|
||||
options: {},
|
||||
state: 'Channel::Filter::IdentifySender',
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Define postmaster filter.',
|
||||
name: '0020_postmaster_filter_auto_response_check',
|
||||
area: 'Postmaster::PreFilter',
|
||||
description: 'Define postmaster filter to identify auto responses to prevent auto replies from Zammad.',
|
||||
options: {},
|
||||
state: 'Channel::Filter::AutoResponseCheck',
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Define postmaster filter.',
|
||||
name: '0030_postmaster_filter_out_of_office_check',
|
||||
area: 'Postmaster::PreFilter',
|
||||
description: 'Define postmaster filter to identify out of office emails for follow up detection and keeping current ticket state.',
|
||||
options: {},
|
||||
state: 'Channel::Filter::OutOfOfficeCheck',
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Define postmaster filter.',
|
||||
name: '0100_postmaster_filter_follow_up_check',
|
||||
area: 'Postmaster::PreFilter',
|
||||
description: 'Define postmaster filter to identify follow ups (based on admin settings).',
|
||||
options: {},
|
||||
state: 'Channel::Filter::FollowUpCheck',
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Define postmaster filter.',
|
||||
name: '0900_postmaster_filter_bounce_check',
|
||||
area: 'Postmaster::PreFilter',
|
||||
description: 'Define postmaster filter to identify postmaster bounced - to handle it as follow up of origin ticket.',
|
||||
options: {},
|
||||
state: 'Channel::Filter::BounceCheck',
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Define postmaster filter.',
|
||||
name: '1000_postmaster_filter_database_check',
|
||||
area: 'Postmaster::PreFilter',
|
||||
description: 'Define postmaster filter for filters managed via admin interface.',
|
||||
options: {},
|
||||
state: 'Channel::Filter::Database',
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Define postmaster filter.',
|
||||
name: '5000_postmaster_filter_ichinga',
|
||||
area: 'Postmaster::PreFilter',
|
||||
description: 'Define postmaster filter for manage Icinga (http://www.icinga.org) emails.',
|
||||
options: {},
|
||||
state: 'Channel::Filter::Icinga',
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Icinga integration',
|
||||
name: 'ichinga_integration',
|
||||
area: 'Integration::Icinga',
|
||||
description: 'Define if Icinga (http://www.icinga.org) is enabled or not.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: true,
|
||||
name: 'ichinga_integration',
|
||||
tag: 'boolean',
|
||||
options: {
|
||||
true => 'yes',
|
||||
false => 'no',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
state: false,
|
||||
preferences: { prio: 1 },
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Sender',
|
||||
name: 'ichinga_sender',
|
||||
area: 'Integration::Icinga',
|
||||
description: 'Define the sender email address of Icinga emails.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: false,
|
||||
name: 'ichinga_sender',
|
||||
tag: 'input',
|
||||
},
|
||||
],
|
||||
},
|
||||
state: 'icinga@monitoring.example.com',
|
||||
frontend: false,
|
||||
preferences: { prio: 2 },
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Auto close',
|
||||
name: 'ichinga_auto_close',
|
||||
area: 'Integration::Icinga',
|
||||
description: 'Define if tickets should be closed if service is recovered.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: true,
|
||||
name: 'ichinga_auto_close',
|
||||
tag: 'boolean',
|
||||
options: {
|
||||
true => 'yes',
|
||||
false => 'no',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
state: true,
|
||||
preferences: { prio: 3 },
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Auto close state',
|
||||
name: 'ichinga_auto_close_state_id',
|
||||
area: 'Integration::Icinga',
|
||||
description: 'Define the ticket state of auto closed tickets.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: false,
|
||||
name: 'ichinga_auto_close_state_id',
|
||||
tag: 'select',
|
||||
relation: 'TicketState',
|
||||
},
|
||||
],
|
||||
},
|
||||
state: 4,
|
||||
preferences: { prio: 4 },
|
||||
frontend: false
|
||||
)
|
||||
end
|
||||
end
|
103
db/seeds.rb
103
db/seeds.rb
|
@ -1525,6 +1525,15 @@ Setting.create_if_not_exists(
|
|||
state: 'Channel::Filter::Trusted',
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Define postmaster filter.',
|
||||
name: '0015_postmaster_filter_identify_sender',
|
||||
area: 'Postmaster::PreFilter',
|
||||
description: 'Define postmaster filter to identify sender user.',
|
||||
options: {},
|
||||
state: 'Channel::Filter::IdentifySender',
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Define postmaster filter.',
|
||||
name: '0020_postmaster_filter_auto_response_check',
|
||||
|
@ -1570,6 +1579,100 @@ Setting.create_if_not_exists(
|
|||
state: 'Channel::Filter::Database',
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Define postmaster filter.',
|
||||
name: '5000_postmaster_filter_ichinga',
|
||||
area: 'Postmaster::PreFilter',
|
||||
description: 'Define postmaster filter for manage Icinga (http://www.icinga.org) emails.',
|
||||
options: {},
|
||||
state: 'Channel::Filter::Icinga',
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Icinga integration',
|
||||
name: 'ichinga_integration',
|
||||
area: 'Integration::Icinga',
|
||||
description: 'Define if Icinga (http://www.icinga.org) is enabled or not.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: true,
|
||||
name: 'ichinga_integration',
|
||||
tag: 'boolean',
|
||||
options: {
|
||||
true => 'yes',
|
||||
false => 'no',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
state: false,
|
||||
preferences: { prio: 1 },
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Sender',
|
||||
name: 'ichinga_sender',
|
||||
area: 'Integration::Icinga',
|
||||
description: 'Define the sender email address of Icinga emails.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: false,
|
||||
name: 'ichinga_sender',
|
||||
tag: 'input',
|
||||
},
|
||||
],
|
||||
},
|
||||
state: 'icinga@monitoring.example.com',
|
||||
frontend: false,
|
||||
preferences: { prio: 2 },
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Auto close',
|
||||
name: 'ichinga_auto_close',
|
||||
area: 'Integration::Icinga',
|
||||
description: 'Define if tickets should be closed if service is recovered.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: true,
|
||||
name: 'ichinga_auto_close',
|
||||
tag: 'boolean',
|
||||
options: {
|
||||
true => 'yes',
|
||||
false => 'no',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
state: true,
|
||||
preferences: { prio: 3 },
|
||||
frontend: false
|
||||
)
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Auto close state',
|
||||
name: 'ichinga_auto_close_state_id',
|
||||
area: 'Integration::Icinga',
|
||||
description: 'Define the ticket state of auto closed tickets.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: false,
|
||||
name: 'ichinga_auto_close_state_id',
|
||||
tag: 'select',
|
||||
relation: 'TicketState',
|
||||
},
|
||||
],
|
||||
},
|
||||
state: 4,
|
||||
preferences: { prio: 4 },
|
||||
frontend: false
|
||||
)
|
||||
|
||||
signature = Signature.create_if_not_exists(
|
||||
id: 1,
|
||||
|
|
|
@ -1996,6 +1996,7 @@ Some Text',
|
|||
data: 'From: me@example.com
|
||||
To: customer@example.com
|
||||
Subject: some subject
|
||||
X-Zammad-Ticket-Followup-State: closed
|
||||
X-Zammad-Ticket-priority: 3 high
|
||||
X-Zammad-Article-sender: System
|
||||
x-Zammad-Article-type: phone
|
||||
|
@ -2006,6 +2007,7 @@ Some Text',
|
|||
success: true,
|
||||
result: {
|
||||
0 => {
|
||||
state: 'new',
|
||||
priority: '3 high',
|
||||
title: 'some subject',
|
||||
},
|
||||
|
@ -2026,6 +2028,7 @@ Some Text',
|
|||
data: 'From: me@example.com
|
||||
To: customer@example.com
|
||||
Subject: some subject
|
||||
X-Zammad-Ticket-Followup-State: closed
|
||||
X-Zammad-Ticket-Priority: 3 high
|
||||
X-Zammad-Article-Sender: System
|
||||
x-Zammad-Article-Type: phone
|
||||
|
@ -2036,6 +2039,7 @@ Some Text',
|
|||
success: true,
|
||||
result: {
|
||||
0 => {
|
||||
state: 'new',
|
||||
priority: '2 normal',
|
||||
title: 'some subject',
|
||||
},
|
||||
|
|
193
test/unit/integration_icinga_test.rb
Normal file
193
test/unit/integration_icinga_test.rb
Normal file
|
@ -0,0 +1,193 @@
|
|||
# encoding: utf-8
|
||||
require 'test_helper'
|
||||
|
||||
class IntegrationIcingaTest < ActiveSupport::TestCase
|
||||
|
||||
test 'base tests' do
|
||||
|
||||
Setting.set('ichinga_integration', true)
|
||||
|
||||
# not matching sender
|
||||
email_raw_string = "To: support@example.com
|
||||
Subject: PROBLEM - host.internal.loc - CPU Load is WARNING
|
||||
User-Agent: Heirloom mailx 12.5 7/5/10
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
Message-Id: <20160131094621.29ECD400F29C-1@monitoring.znuny.com>
|
||||
From: icinga_not_matching@monitoring.example.com (icinga)
|
||||
|
||||
***** Icinga *****
|
||||
|
||||
Notification Type: PROBLEM
|
||||
|
||||
Service: CPU Load
|
||||
Host: host.internal.loc
|
||||
Address:=20
|
||||
State: WARNING
|
||||
|
||||
Date/Time: 2016-01-31 10:46:20 +0100
|
||||
|
||||
Additional Info: WARNING - load average: 3.44, 0.99, 0.35
|
||||
|
||||
Comment: [] =
|
||||
"
|
||||
|
||||
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
assert_equal('new', ticket_p.state.name)
|
||||
assert(ticket_p.preferences)
|
||||
assert_not(ticket_p.preferences['integration'])
|
||||
assert_not(ticket_p.preferences['ichinga'])
|
||||
|
||||
# matching sender - CPU Load/host.internal.loc
|
||||
email_raw_string = "To: support@example.com
|
||||
Subject: PROBLEM - host.internal.loc - CPU Load is WARNING
|
||||
User-Agent: Heirloom mailx 12.5 7/5/10
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
Message-Id: <20160131094621.29ECD400F29C-2@monitoring.znuny.com>
|
||||
From: icinga@monitoring.example.com (icinga)
|
||||
|
||||
***** Icinga *****
|
||||
|
||||
Notification Type: PROBLEM
|
||||
|
||||
Service: CPU Load
|
||||
Host: host.internal.loc
|
||||
Address:=20
|
||||
State: WARNING
|
||||
|
||||
Date/Time: 2016-01-31 10:46:20 +0100
|
||||
|
||||
Additional Info: WARNING - load average: 3.44, 0.99, 0.35
|
||||
|
||||
Comment: [] =
|
||||
"
|
||||
|
||||
ticket_1, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
assert_equal('new', ticket_1.state.name)
|
||||
assert(ticket_1.preferences)
|
||||
assert(ticket_1.preferences['integration'])
|
||||
assert_equal('ichinga', ticket_1.preferences['integration'])
|
||||
assert(ticket_1.preferences['ichinga'])
|
||||
assert_equal('host.internal.loc', ticket_1.preferences['ichinga']['host'])
|
||||
assert_equal('CPU Load', ticket_1.preferences['ichinga']['service'])
|
||||
assert_equal('WARNING', ticket_1.preferences['ichinga']['state'])
|
||||
|
||||
# matching sender - Disk Usage 123/host.internal.loc
|
||||
email_raw_string = "To: support@example.com
|
||||
Subject: PROBLEM - host.internal.loc - Disk Usage 123 is WARNING
|
||||
User-Agent: Heirloom mailx 12.5 7/5/10
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
Message-Id: <20160131094621.29ECD400F29C-3@monitoring.znuny.com>
|
||||
From: icinga@monitoring.example.com (icinga)
|
||||
|
||||
***** Icinga *****
|
||||
|
||||
Notification Type: PROBLEM
|
||||
|
||||
Service: Disk Usage 123
|
||||
Host: host.internal.loc
|
||||
Address:=20
|
||||
State: WARNING
|
||||
|
||||
Date/Time: 2016-01-31 10:46:20 +0100
|
||||
|
||||
Additional Info: WARNING - load average: 3.44, 0.99, 0.35
|
||||
|
||||
Comment: [] =
|
||||
"
|
||||
|
||||
ticket_2, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
assert_equal('new', ticket_2.state.name)
|
||||
assert(ticket_2.preferences)
|
||||
assert(ticket_2.preferences['integration'])
|
||||
assert_equal('ichinga', ticket_2.preferences['integration'])
|
||||
assert(ticket_2.preferences['ichinga'])
|
||||
assert_equal('host.internal.loc', ticket_2.preferences['ichinga']['host'])
|
||||
assert_equal('Disk Usage 123', ticket_2.preferences['ichinga']['service'])
|
||||
assert_equal('WARNING', ticket_2.preferences['ichinga']['state'])
|
||||
assert_not_equal(ticket_2.id, ticket_1.id)
|
||||
|
||||
# matching sender - follow up - CPU Load/host.internal.loc
|
||||
email_raw_string = "To: support@example.com
|
||||
Subject: PROBLEM - host.internal.loc - CPU Load is WARNING
|
||||
User-Agent: Heirloom mailx 12.5 7/5/10
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
Message-Id: <20160131094621.29ECD400F29C-4@monitoring.znuny.com>
|
||||
From: icinga@monitoring.example.com (icinga)
|
||||
|
||||
***** Icinga *****
|
||||
|
||||
Notification Type: PROBLEM
|
||||
|
||||
Service: CPU Load
|
||||
Host: host.internal.loc
|
||||
Address:=20
|
||||
State: WARNING
|
||||
|
||||
Date/Time: 2016-01-31 10:46:20 +0100
|
||||
|
||||
Additional Info: WARNING - load average: 3.44, 0.99, 0.35
|
||||
|
||||
Comment: [] =
|
||||
"
|
||||
|
||||
ticket_1_1, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
assert_equal('new', ticket_1_1.state.name)
|
||||
assert(ticket_1_1.preferences)
|
||||
assert(ticket_1_1.preferences['integration'])
|
||||
assert_equal('ichinga', ticket_1_1.preferences['integration'])
|
||||
assert(ticket_1_1.preferences['ichinga'])
|
||||
assert_equal('host.internal.loc', ticket_1_1.preferences['ichinga']['host'])
|
||||
assert_equal('CPU Load', ticket_1_1.preferences['ichinga']['service'])
|
||||
assert_equal('WARNING', ticket_1_1.preferences['ichinga']['state'])
|
||||
assert_equal(ticket_1.id, ticket_1_1.id)
|
||||
|
||||
# matching sender - follow up - recovery - CPU Load/host.internal.loc
|
||||
email_raw_string = "To: support@example.com
|
||||
Subject: PROBLEM - host.internal.loc - CPU Load is WARNING
|
||||
User-Agent: Heirloom mailx 12.5 7/5/10
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
Message-Id: <20160131094621.29ECD400F29C-5@monitoring.znuny.com>
|
||||
From: icinga@monitoring.example.com (icinga)
|
||||
|
||||
***** Icinga *****
|
||||
|
||||
Notification Type: RECOVERY
|
||||
|
||||
Service: CPU Load
|
||||
Host: host.internal.loc
|
||||
Address:=20
|
||||
State: OK
|
||||
|
||||
Date/Time: 2016-01-31 10:48:02 +0100
|
||||
|
||||
Additional Info: OK - load average: 1.62, 1.17, 0.49
|
||||
|
||||
Comment: [] =
|
||||
"
|
||||
|
||||
ticket_1_2, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
assert_equal(ticket_1.id, ticket_1_2.id)
|
||||
assert_equal('closed', ticket_1_2.state.name)
|
||||
assert(ticket_1_2.preferences)
|
||||
assert(ticket_1_2.preferences['integration'])
|
||||
assert_equal('ichinga', ticket_1_2.preferences['integration'])
|
||||
assert(ticket_1_2.preferences['ichinga'])
|
||||
assert_equal('host.internal.loc', ticket_1_2.preferences['ichinga']['host'])
|
||||
assert_equal('CPU Load', ticket_1_2.preferences['ichinga']['service'])
|
||||
assert_equal('WARNING', ticket_1_2.preferences['ichinga']['state'])
|
||||
|
||||
#Setting.set('ichinga_integration', false)
|
||||
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue