2 #Copyright (C) 2009 Gabes Jean, naparuba@gmail.com
4 #This file is part of Shinken.
6 #Shinken is free software: you can redistribute it and/or modify
7 #it under the terms of the GNU Affero General Public License as published by
8 #the Free Software Foundation, either version 3 of the License, or
9 #(at your option) any later version.
11 #Shinken is distributed in the hope that it will be useful,
12 #but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 #GNU Affero General Public License for more details.
16 #You should have received a copy of the GNU Affero General Public License
17 #along with Shinken. If not, see <http://www.gnu.org/licenses/>.
20 #This Class is an example of an Arbiter module
21 #Here for the configuration phase AND running one
24 #This text is print at the import
25 print "Detected module : NSCA module for Arbiter"
32 from ctypes
import create_string_buffer
35 from shinken
.basemodule
import BaseModule
36 from shinken
.external_command
import ExternalCommand
39 'type' : 'nsca_server',
41 'phases' : ['running'],
44 def decrypt_xor(data
, key
):
46 crypted
= [chr(ord(data
[i
]) ^
ord(key
[i
% keylen
])) for i
in xrange(len(data
))]
47 return ''.join(crypted
)
49 #called by the plugin manager to get a broker
50 def get_instance(plugin
):
51 print "Get a NSCA arbiter module for plugin %s" % plugin
.get_name()
53 if hasattr(plugin
, 'host'):
54 if plugin
.host
== '*':
60 if hasattr(plugin
, 'port'):
61 port
= int(plugin
.port
)
64 if hasattr(plugin
, 'encryption_method'):
65 encryption_method
= int(plugin
.encryption_method
)
68 if hasattr(plugin
, 'password'):
69 password
= plugin
.password
73 instance
= NSCA_arbiter(plugin
, host
, port
, encryption_method
, password
)
77 #Just print some stuff
78 class NSCA_arbiter(BaseModule
):
79 def __init__(self
, modconf
, host
, port
, encryption_method
, password
):
80 BaseModule
.__init
__(self
, modconf
)
83 self
.encryption_method
= encryption_method
84 self
.password
= password
85 self
.rng
= random
.Random(password
)
88 #Ok, main function that is called in the CONFIGURATION phase
89 def get_objects(self
):
90 print "[Dummy] ask me for objects to return"
92 h
= {'name' : 'dummy host from dummy arbiter module',
97 print "[Dummy] Returning to Arbiter the hosts:", r
100 def send_init_packet(self
, socket
):
104 128-131 : unix timestamp
106 init_packet
=create_string_buffer(132)
107 iv
= ''.join([chr(self
.rng
.randrange(256)) for i
in xrange(128)])
108 init_packet
.raw
=struct
.pack("!128sI",iv
,int(time
.mktime(time
.gmtime())))
109 socket
.send(init_packet
)
112 def read_check_result(self
, data
, iv
):
114 Read the check result
121 204-715 : output of the plugin
127 if self
.encryption_method
== 1:
128 data
= decrypt_xor(data
,self
.password
)
129 data
= decrypt_xor(data
,iv
)
131 (version
, pad1
, crc32
, timestamp
, rc
, hostname_dirty
, service_dirty
, output_dirty
, pad2
) = struct
.unpack("!hhIIh64s128s512sh",data
)
132 hostname
, sep
, dish
= hostname_dirty
.partition("\0")
133 service
, sep
, dish
= service_dirty
.partition("\0")
134 output
, sep
, dish
= output_dirty
.partition("\0")
135 return (timestamp
, rc
, hostname
, service
, output
)
137 def post_command(self
, timestamp
, rc
, hostname
, service
, output
):
139 Send a check result command to the arbiter
141 if len(service
) == 0:
142 extcmd
= "[%lu] PROCESS_HOST_CHECK_RESULT;%s;%d;%s\n" % (timestamp
,hostname
,rc
,output
)
144 extcmd
= "[%lu] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n" % (timestamp
,hostname
,service
,rc
,output
)
146 e
= ExternalCommand(extcmd
)
150 # When you are in "external" mode, that is the main loop of your process
152 self
.set_exit_handler()
155 server
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
156 server
.setblocking(0)
157 server
.bind((self
.host
, self
.port
))
158 server
.listen(backlog
)
163 while not self
.interrupted
:
164 inputready
,outputready
,exceptready
= select
.select(input,[],[], 1)
168 # handle the server socket
169 client
, address
= server
.accept()
170 iv
= self
.send_init_packet(client
)
174 # handle all other sockets
177 databuffer
[s
] += data
180 if len(databuffer
[s
]) == 720:
181 # end-of-transmission or an empty line was received
182 (timestamp
, rc
, hostname
, service
, output
)=self
.read_check_result(databuffer
[s
],IVs
[s
])
185 self
.post_command(timestamp
,rc
,hostname
,service
,output
)
188 except Exception , exp
: