4 from os.path import dirname, exists, join
9 from monitor import config
10 from monitor.database.dborm import zab_session as session
11 from monitor.database.zabbixapi.model import *
12 from monitor.database.zabbixapi.emailZabbix import *
13 from monitor.database.zabbixapi import defines
14 from monitor.util.file import *
18 HOSTGROUP_NAME="%s_hostgroup"
19 USERGROUP_NAME="%s_usergroup"
21 DISCOVERY_RULE_NAME="discovery rule for %s"
22 DISCOVERY_ACTION_NAME="Auto-discover %s action"
23 ESCALATION_ACTION_NAME="Escalation Action for %s"
25 def delete_site(loginbase):
27 # get host group, usrgrp
28 # get all users in usrgrp, delete each
29 usergroupname = USERGROUP_NAME % loginbase
30 hostgroupname = HOSTGROUP_NAME % loginbase
31 discovery_action_name = DISCOVERY_ACTION_NAME % loginbase
32 discovery_rule_name = DISCOVERY_RULE_NAME % loginbase
33 escalation_action_name = ESCALATION_ACTION_NAME % loginbase
35 ug = UsrGrp.get_by(name=usergroupname)
37 for user in ug.user_list:
38 # remove user from group, if a member of no other groups,
44 hg = HostGroup.get_by(name=hostgroupname)
46 # figure out how to delete all the hosts...
47 # NOTE: hosts are listed in hg.host_list
48 for host in hg.host_list:
53 dr = DiscoveryRule.get_by(name=discovery_rule_name)
56 da = Action.get_by(name=discovery_action_name)
59 ea = Action.get_by(name=escalation_action_name)
65 # NOTE: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
66 ## These functions can ONLY be run when the server and gui are offline.
67 ## Any changes to the db while this is running risks introducing a failure
68 ## to commit, and therefore error.
69 # NOTE: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
72 # update mediatype for email.
73 ############################### MAIL
74 print "checking for MediaType Email"
75 mediatype = MediaType.get_by(description="Email")
77 print "ERROR: There is no defined media type for 'Email'"
78 raise Exception("No Email Media type in Zabbix db")
80 print "checking for correct configuration"
81 mediatype = MediaType.get_by(smtp_email=config.from_email)
83 mediatype = MediaType.get_by(description="Email")
84 # NOTE: assumes smtp server is local to this machine.
85 print "updating email server configuration"
86 mediatype.smtp_server='localhost'
87 mediatype.smtp_helo=".".join(config.MONITOR_HOSTNAME.split('.')[1:])
88 mediatype.smtp_email=config.from_email
90 ############################# EMAIL
91 mailtxt.reformat({'hostname' : config.MONITOR_HOSTNAME,
92 'support_email' : config.support_email})
94 ############################### CENTRAL SERVER
95 print "checking zabbix server host info"
96 zabbixserver = Host.get_by(host="ZABBIX Server")
98 # TODO: verify that this works. it has failed once on fresh
99 # install... not sure why.
100 print "Removing default Zabbix server entry"
101 zabbixserver.delete()
103 # NOTE: creating a host and assigning a template cannot work
104 # due to the crazy item, trigger, action
105 # copying that the php code does during a host add.
106 # NOTE: Instead, reformat any *xml.in templates and import those
107 # during /etc/plc.d/monitor sync
108 for file in glob.glob("%s/zabbix/templates/*.xml.in" % config.MONITOR_SCRIPT_ROOT):
109 if 'zabbix_server' in file:
111 args = {'hostname' : config.MONITOR_HOSTNAME, 'ip' : config.MONITOR_IP}
112 dumpFile(file[:-3], buf % args)
115 ##################### SCRIPTS
116 ## TODO: add calls to check/reset the boot states.
117 print "checking scripts"
118 script1 = Script.find_or_create(name="RebootNode",
120 'command':"%s/reboot.py {HOST.CONN}" % config.MONITOR_SCRIPT_ROOT,
121 'host_access':3 # r/w)
123 script2 = Script.find_or_create(name="NMap",
125 'command':"/usr/bin/nmap -A {HOST.CONN}",
126 'host_access':2 # r/o)
130 def merge_iplist(iplist):
131 # TODO: rewrite addresses as x.x.x.y-z rather than x.x.x.y,x.x.x.z if y-z==1
132 ips = iplist.split(',')
137 fields = ip.split('.')
138 first = ".".join(fields[:2])
139 last = int(fields[3])
147 def setup_site(loginbase, techemail, piemail, iplist):
149 # TODO: send a message when host is discovered.
151 # TODO: update 'discovered' hosts with dns name.
152 # TODO: remove old nodes that are no longer in the plcdb.
153 # TODO: remove old users that are no longer in the plcdb.
154 # TODO: consider creating two user groups for Tech & PI emails
156 # NOTE: setup default valus for EMAIL
157 mailtxt.reformat({'hostname' : config.MONITOR_HOSTNAME,
158 'support_email' : config.support_email})
160 # NOTE: verify arguments
161 if len(iplist) > 255:
162 raise Exception("iplist length is too long!")
164 BI_WEEKLY_ESC_PERIOD = int(60*60*24)
165 #BI_WEEKLY_ESC_PERIOD = int(60) # testing...
168 site_user_group = UsrGrp.find_or_create(name=USERGROUP_NAME % loginbase)
169 for user in set(techemail + piemail + [config.cc_email]):
170 if not user: continue
172 u = User.find_or_create(alias=user, type=1,
173 set_if_new={'passwd' : md5.md5(user).hexdigest()},
174 # exec_if_new avoids creating a Media object that
175 # will not actually be used, if the user already exists
176 exec_if_new=lambda obj: \
177 obj.media_list.append( Media(mediatypeid=1, sendto=user)))
179 if site_user_group not in u.usrgrp_list:
180 u.append_group(site_user_group)
183 plc_host_group = HostGroup.find_or_create(name="MyPLC Hosts")
184 site_host_group = HostGroup.find_or_create(name=HOSTGROUP_NAME % loginbase)
185 plctemplate = Host.get_by(host="Template_Linux_PLC_Host")
186 escalation_action_name = ESCALATION_ACTION_NAME % loginbase
187 discovery_action_name = DISCOVERY_ACTION_NAME % loginbase
188 discovery_rule_name = DISCOVERY_RULE_NAME % loginbase
191 if site_host_group not in site_user_group.hostgroup_list:
192 site_user_group.append_hostgroup(site_host_group)
194 # DISCOVERY RULE & CHECK
195 dr = DiscoveryRule.find_or_create(name=discovery_rule_name,
198 set_if_new = {'iprange':iplist},
199 exec_if_new=lambda obj: \
200 obj.discoverycheck_list.append( DiscoveryCheck(type=9,
201 key_="system.uname", ports=10050) )
203 if dr.iprange != iplist:
207 # DISCOVERY ACTION for these servers
208 a = Action.find_or_create(name=discovery_action_name,
209 eventsource=defines.EVENT_SOURCE_DISCOVERY,
210 status=defines.DRULE_STATUS_ACTIVE,
211 evaltype=defines.ACTION_EVAL_TYPE_AND_OR)
212 if len(a.actioncondition_list) == 0:
213 a.actioncondition_list=[
216 conditiontype=defines.CONDITION_TYPE_DHOST_IP,
217 operator=defines.CONDITION_OPERATOR_EQUAL,
219 # AND, Service type is Zabbix agent
221 conditiontype=defines.CONDITION_TYPE_DSERVICE_TYPE,
222 operator=defines.CONDITION_OPERATOR_EQUAL,
223 value=defines.SVC_AGENT),
224 # AND, Received system.uname value like 'Linux'
226 conditiontype=defines.CONDITION_TYPE_DVALUE,
227 operator=defines.CONDITION_OPERATOR_LIKE,
229 # AND, Discovery status is Discover
231 conditiontype=defines.CONDITION_TYPE_DSTATUS,
232 operator=defines.CONDITION_OPERATOR_EQUAL,
233 value=defines.DOBJECT_STATUS_DISCOVER),
236 a.actionoperation_list=[
239 operationtype=defines.OPERATION_TYPE_HOST_ADD,
240 object=0, objectid=0,
241 esc_period=0, esc_step_from=1, esc_step_to=1),
242 # Add To Group PLC Hosts
244 operationtype=defines.OPERATION_TYPE_GROUP_ADD,
245 object=0, objectid=plc_host_group.groupid,
246 esc_period=0, esc_step_from=1, esc_step_to=1),
247 # Add To Group LoginbaseSiteGroup
249 operationtype=defines.OPERATION_TYPE_GROUP_ADD,
250 object=0, objectid=site_host_group.groupid,
251 esc_period=0, esc_step_from=1, esc_step_to=1),
252 # Link to Template 'Template_Linux_Minimal'
254 operationtype=defines.OPERATION_TYPE_TEMPLATE_ADD,
255 object=0, objectid=plctemplate.hostid,
256 esc_period=0, esc_step_from=1, esc_step_to=1),
259 # TODO: verify iplist is up-to-date
260 # NOTE: len(a.actioncondition_list) > 0
261 ip_condition = a.actioncondition_list[0]
262 assert ip_condition.conditiontype == defines.CONDITION_TYPE_DHOST_IP
263 if ip_condition.value != iplist:
264 ip_condition.value = iplist
266 # ESCALATION ACTION for these servers
267 ea = Action.find_or_create(name=escalation_action_name,
268 eventsource=defines.EVENT_SOURCE_TRIGGERS,
269 status=defines.ACTION_STATUS_ENABLED,
270 evaltype=defines.ACTION_EVAL_TYPE_AND_OR,
271 esc_period=BI_WEEKLY_ESC_PERIOD, # three days
274 'r_shortdata':"Thank you for maintaining {HOSTNAME}!",
275 'r_longdata': mailtxt.thankyou_nodeup, }
277 if len(ea.actioncondition_list) == 0:
278 # THEN this is a new entry
279 print "SETTING UP ESCALATION ACTION"
280 ea.actioncondition_list=[
281 ActionCondition(conditiontype=defines.CONDITION_TYPE_TRIGGER_VALUE,
282 operator=defines.CONDITION_OPERATOR_EQUAL,
283 value=defines.TRIGGER_VALUE_TRUE),
284 ActionCondition(conditiontype=defines.CONDITION_TYPE_TRIGGER_NAME,
285 operator=defines.CONDITION_OPERATOR_LIKE,
286 value="is unreachable"),
287 ActionCondition(conditiontype=defines.CONDITION_TYPE_HOST_GROUP,
288 operator=defines.CONDITION_OPERATOR_EQUAL,
289 value=site_host_group.groupid),
291 ea.actionoperation_list=[
293 ActionOperation(operationtype=defines.OPERATION_TYPE_MESSAGE,
294 shortdata=mailtxt.nodedown_one_subject,
295 longdata=mailtxt.nodedown_one,
296 object=defines.OPERATION_OBJECT_GROUP,
297 objectid=site_user_group.usrgrpid,
298 esc_period=0, esc_step_to=3, esc_step_from=3,
299 operationcondition_list=[ OperationConditionNotAck() ] ),
300 ActionOperation(operationtype=defines.OPERATION_TYPE_MESSAGE,
301 shortdata=mailtxt.nodedown_one_subject,
302 longdata=mailtxt.nodedown_one,
303 object=defines.OPERATION_OBJECT_GROUP,
304 objectid=site_user_group.usrgrpid,
305 esc_period=0, esc_step_to=7, esc_step_from=7,
306 operationcondition_list=[ OperationConditionNotAck() ] ),
308 ActionOperation(operationtype=defines.OPERATION_TYPE_COMMAND,
309 esc_step_from=10, esc_step_to=10,
312 longdata="%s:%s/checkslices.py {HOSTNAME} disablesite" % ( config.MONITOR_HOSTNAME, config.MONITOR_SCRIPT_ROOT ),
313 operationcondition_list=[ OperationConditionNotAck() ]),
314 ActionOperation(operationtype=defines.OPERATION_TYPE_MESSAGE,
315 shortdata=mailtxt.nodedown_two_subject,
316 longdata=mailtxt.nodedown_two,
317 esc_step_from=10, esc_step_to=10,
319 object=defines.OPERATION_OBJECT_GROUP,
320 objectid=site_user_group.usrgrpid,
321 operationcondition_list=[ OperationConditionNotAck() ] ),
322 ActionOperation(operationtype=defines.OPERATION_TYPE_MESSAGE,
323 shortdata=mailtxt.nodedown_two_subject,
324 longdata=mailtxt.nodedown_two,
325 esc_step_from=14, esc_step_to=14,
327 object=defines.OPERATION_OBJECT_GROUP,
328 objectid=site_user_group.usrgrpid,
329 operationcondition_list=[ OperationConditionNotAck() ] ),
332 ActionOperation(operationtype=defines.OPERATION_TYPE_COMMAND,
333 esc_step_from=17, esc_step_to=17,
336 longdata="%s:%s/checkslices.py {HOSTNAME} disableslices" % ( config.MONITOR_HOSTNAME, config.MONITOR_SCRIPT_ROOT ),
337 # TODO: send notice to users of slices
338 operationcondition_list=[ OperationConditionNotAck() ]),
339 ActionOperation(operationtype=defines.OPERATION_TYPE_MESSAGE,
340 shortdata=mailtxt.nodedown_three_subject,
341 longdata=mailtxt.nodedown_three,
342 esc_step_from=17, esc_step_to=17,
344 object=defines.OPERATION_OBJECT_GROUP,
345 objectid=site_user_group.usrgrpid,
346 operationcondition_list=[ OperationConditionNotAck() ] ),
348 ActionOperation(operationtype=defines.OPERATION_TYPE_COMMAND,
349 esc_step_from=21, esc_step_to=0,
350 esc_period=int(BI_WEEKLY_ESC_PERIOD*3.5),
352 longdata="%s:%s/checkslices.py {HOSTNAME} forever" % ( config.MONITOR_HOSTNAME, config.MONITOR_SCRIPT_ROOT),
353 operationcondition_list=[ OperationConditionNotAck() ]),
354 ActionOperation(operationtype=defines.OPERATION_TYPE_MESSAGE,
355 shortdata=mailtxt.nodedown_four_subject,
356 longdata=mailtxt.nodedown_four,
357 esc_step_from=21, esc_step_to=0,
358 esc_period=int(BI_WEEKLY_ESC_PERIOD*3.5),
359 object=defines.OPERATION_OBJECT_GROUP,
360 objectid=site_user_group.usrgrpid,
361 operationcondition_list=[ OperationConditionNotAck() ] ),
364 if __name__ == "__main__":