* add code to import xml templates using curl.
[monitor.git] / zabbix / zabbixsite.py
1 #!/usr/bin/python
2
3 from os import getcwd
4 from os.path import dirname, exists, join
5 import sys
6 import md5
7 import glob
8
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 *
15
16
17
18 HOSTGROUP_NAME="%s_hostgroup"
19 USERGROUP_NAME="%s_usergroup"
20         
21 DISCOVERY_RULE_NAME="discovery rule for %s"
22 DISCOVERY_ACTION_NAME="Auto-discover %s action"
23 ESCALATION_ACTION_NAME="Escalation Action for %s"
24
25 def delete_site(loginbase):
26
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
34
35         ug = UsrGrp.get_by(name=usergroupname)
36         if ug:
37                 for user in ug.user_list:
38                         # remove user from group, if a member of no other groups, 
39                         # delete user.
40                         #user.delete()
41                         pass
42                 ug.delete()
43
44         hg = HostGroup.get_by(name=hostgroupname)
45         if hg: 
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:
49                         host.delete()
50                 hg.delete()
51
52         # delete dr
53         dr = DiscoveryRule.get_by(name=discovery_rule_name)
54         if dr: dr.delete()
55
56         da = Action.get_by(name=discovery_action_name)
57         if da: da.delete()
58
59         ea = Action.get_by(name=escalation_action_name)
60         if ea: ea.delete()
61
62         return
63
64
65 def setup_global():
66         # GLOBAL:
67         #       update mediatype for email.
68         ############################### MAIL
69         print "checking for MediaType Email"
70         mediatype = MediaType.get_by(description="Email")
71         if not mediatype:
72                 print "ERROR:  There is no defined media type for 'Email'"
73                 raise Exception("No Email Media type in Zabbix db")
74
75         print "checking for correct configuration"
76         mediatype = MediaType.get_by(smtp_email=config.from_email)
77         if not mediatype:
78                 mediatype = MediaType.get_by(description="Email")
79                 # NOTE: assumes smtp server is local to this machine.
80                 print "updating email server configuration"
81                 mediatype.smtp_server='localhost'
82                 mediatype.smtp_helo=".".join(config.MONITOR_HOSTNAME.split('.')[1:])
83                 mediatype.smtp_email=config.from_email
84
85         ############################# EMAIL
86         mailtxt.reformat({'hostname' : config.MONITOR_HOSTNAME, 
87                                           'support_email' : config.support_email})
88
89         ############################### CENTRAL SERVER
90         print "checking zabbix server host info"
91         zabbixserver = Host.get_by(host="ZABBIX Server")
92         if zabbixserver:
93                 print "Removing default Zabbix server entry"
94                 zabbixserver.delete()
95
96                 # NOTE: creating a host and assigning a template cannot work 
97                 #       due to the crazy item, trigger, action
98                 #               copying that the php code does during a host add.
99                 # NOTE: Instead, reformat any *xml.in templates and import those
100                 #               during /etc/plc.d/monitor sync
101                 for file in glob.glob("/usr/share/monitor/templates/*.xml.in"):
102                         if 'zabbix_server' in file:
103                                 buf = loadFile(file)
104                                 args = {'hostname' : config.MONITOR_HOSTNAME, 'ip' : config.MONITOR_IP}
105                                 dumpFile(file[:-3], buf % args)
106
107
108         ##################### SCRIPTS 
109         ## TODO: add calls to check/reset the boot states.
110         print "checking scripts"
111         script1 = Script.find_or_create(name="RebootNode",
112                                                                         set_if_new = {
113                                                                                 'command':"/usr/share/monitor-server/reboot.py {HOST.CONN}",
114                                                                                 'host_access':3 # r/w)
115                                                                         })
116         script2 = Script.find_or_create(name="NMap",
117                                                         set_if_new = {
118                                                                 'command':"/usr/bin/nmap -A {HOST.CONN}",
119                                                                 'host_access':2 # r/o)
120                                                 })
121         return
122
123 def setup_site(loginbase, techemail, piemail, iplist):
124
125         # TODO: send a message when host is discovered.
126
127         # TODO: update 'discovered' hosts with dns name.
128         # TODO: remove old nodes that are no longer in the plcdb.
129         # TODO: remove old users that are no longer in the plcdb.
130         # TODO: consider creating two user groups for Tech & PI emails
131
132         BI_WEEKLY_ESC_PERIOD = int(60*60*24)
133         BI_WEEKLY_ESC_PERIOD = int(60) # testing...
134
135         # User Group
136         site_user_group = UsrGrp.find_or_create(name=USERGROUP_NAME % loginbase)
137         for user in set(techemail + piemail + [config.cc_email]):
138                 if not user: continue
139                 # USER
140                 u = User.find_or_create(alias=user, type=1,
141                                                                 set_if_new={'passwd' : md5.md5(user).hexdigest()},
142                                                                 # exec_if_new avoids creating a Media object that
143                                                                 # will not actually be used, if the user already exists
144                                                                 exec_if_new=lambda obj: \
145                                                                 obj.media_list.append( Media(mediatypeid=1, sendto=user)))
146
147                 if site_user_group not in u.usrgrp_list:
148                         u.append_group(site_user_group)
149
150         # HOST GROUP
151         plc_host_group = HostGroup.find_or_create(name="MyPLC Hosts")
152         site_host_group = HostGroup.find_or_create(name=HOSTGROUP_NAME % loginbase)
153         plctemplate = Host.get_by(host="Template_Linux_PLC_Host")
154         escalation_action_name = ESCALATION_ACTION_NAME % loginbase
155         discovery_action_name = DISCOVERY_ACTION_NAME % loginbase
156         discovery_rule_name = DISCOVERY_RULE_NAME % loginbase
157
158         # ADD hg to ug
159         if site_host_group not in site_user_group.hostgroup_list:
160                 site_user_group.append_hostgroup(site_host_group)
161
162         # DISCOVERY RULE & CHECK
163         dr = DiscoveryRule.find_or_create(name=discovery_rule_name,
164                           delay=3600,
165                           proxy_hostid=0,
166                           set_if_new = {'iprange':iplist},
167                           exec_if_new=lambda obj: \
168                                 obj.discoverycheck_list.append( DiscoveryCheck(type=9, 
169                                                                                 key_="system.uname", ports=10050) )
170                         )
171         if dr.iprange != iplist:
172                 if len(iplist) < 255:
173                         dr.iprange = iplist
174                 else:
175                         raise Exception("iplist length is too long!")
176                 
177
178         # DISCOVERY ACTION for these servers
179         a = Action.find_or_create(name=discovery_action_name,
180                         eventsource=defines.EVENT_SOURCE_DISCOVERY,
181                         status=defines.DRULE_STATUS_ACTIVE,
182                         evaltype=defines.ACTION_EVAL_TYPE_AND_OR)
183         if len(a.actioncondition_list) == 0:
184                 a.actioncondition_list=[
185                                         # Host IP Matches
186                                         ActionCondition(
187                                                 conditiontype=defines.CONDITION_TYPE_DHOST_IP,
188                                                 operator=defines.CONDITION_OPERATOR_EQUAL,
189                                                 value=iplist),
190                                         # AND, Service type is Zabbix agent
191                                         ActionCondition(
192                                                 conditiontype=defines.CONDITION_TYPE_DSERVICE_TYPE,
193                                                 operator=defines.CONDITION_OPERATOR_EQUAL,
194                                                 value=defines.SVC_AGENT),
195                                         # AND, Received system.uname value like 'Linux'
196                                         ActionCondition(
197                                                 conditiontype=defines.CONDITION_TYPE_DVALUE,
198                                                 operator=defines.CONDITION_OPERATOR_LIKE,
199                                                 value="Linux"),
200                                         # AND, Discovery status is Discover
201                                         ActionCondition(
202                                                 conditiontype=defines.CONDITION_TYPE_DSTATUS,
203                                                 operator=defines.CONDITION_OPERATOR_EQUAL,
204                                                 value=defines.DOBJECT_STATUS_DISCOVER),
205                                 ]
206                                 # THEN
207                 a.actionoperation_list=[
208                                         # Add Host
209                                         ActionOperation(
210                                                 operationtype=defines.OPERATION_TYPE_HOST_ADD,
211                                                 object=0, objectid=0,
212                                                 esc_period=0, esc_step_from=1, esc_step_to=1),
213                                         # Add To Group PLC Hosts
214                                         ActionOperation(
215                                                 operationtype=defines.OPERATION_TYPE_GROUP_ADD,
216                                                 object=0, objectid=plc_host_group.groupid,
217                                                 esc_period=0, esc_step_from=1, esc_step_to=1),
218                                         # Add To Group LoginbaseSiteGroup
219                                         ActionOperation(
220                                                 operationtype=defines.OPERATION_TYPE_GROUP_ADD,
221                                                 object=0, objectid=site_host_group.groupid,
222                                                 esc_period=0, esc_step_from=1, esc_step_to=1),
223                                         # Link to Template 'Template_Linux_Minimal'
224                                         ActionOperation(
225                                                 operationtype=defines.OPERATION_TYPE_TEMPLATE_ADD,
226                                                 object=0, objectid=plctemplate.hostid,
227                                                 esc_period=0, esc_step_from=1, esc_step_to=1),
228                                 ]
229         else:
230                 # TODO: verify iplist is up-to-date
231                 pass
232
233         # ESCALATION ACTION for these servers
234         ea = Action.find_or_create(name=escalation_action_name,
235                         eventsource=defines.EVENT_SOURCE_TRIGGERS,
236                         status=defines.ACTION_STATUS_ENABLED,
237                         evaltype=defines.ACTION_EVAL_TYPE_AND_OR,
238                         esc_period=BI_WEEKLY_ESC_PERIOD,        # three days
239                         recovery_msg=1,
240                         set_if_new={
241                                 'r_shortdata':"Thank you for maintaining {HOSTNAME}!",
242                                 'r_longdata': mailtxt.thankyou_nodeup, }
243                         )
244         if len(ea.actioncondition_list) == 0:
245                         # THEN this is a new entry
246                 print "SETTING UP ESCALATION ACTION"
247                 ea.actioncondition_list=[
248                                 ActionCondition(conditiontype=defines.CONDITION_TYPE_TRIGGER_VALUE, 
249                                                                 operator=defines.CONDITION_OPERATOR_EQUAL, 
250                                                                 value=defines.TRIGGER_VALUE_TRUE),
251                                 ActionCondition(conditiontype=defines.CONDITION_TYPE_TRIGGER_NAME, 
252                                                                 operator=defines.CONDITION_OPERATOR_LIKE, 
253                                                                 value="is unreachable"),
254                                 ActionCondition(conditiontype=defines.CONDITION_TYPE_HOST_GROUP, 
255                                                                 operator=defines.CONDITION_OPERATOR_EQUAL, 
256                                                                 value=site_host_group.groupid),
257                         ]
258                 ea.actionoperation_list=[
259                                 # STAGE 1
260                                 ActionOperation(operationtype=defines.OPERATION_TYPE_MESSAGE,
261                                         shortdata=mailtxt.nodedown_one_subject,
262                                         longdata=mailtxt.nodedown_one,
263                                         object=defines.OPERATION_OBJECT_GROUP, 
264                                         objectid=site_user_group.usrgrpid, 
265                                         esc_period=0, esc_step_to=3, esc_step_from=3, 
266                                         operationcondition_list=[ OperationConditionNotAck() ] ),
267                                 ActionOperation(operationtype=defines.OPERATION_TYPE_MESSAGE,
268                                         shortdata=mailtxt.nodedown_one_subject,
269                                         longdata=mailtxt.nodedown_one,
270                                         object=defines.OPERATION_OBJECT_GROUP, 
271                                         objectid=site_user_group.usrgrpid, 
272                                         esc_period=0, esc_step_to=7, esc_step_from=7, 
273                                         operationcondition_list=[ OperationConditionNotAck() ] ),
274                                 # STAGE 2
275                                 ActionOperation(operationtype=defines.OPERATION_TYPE_COMMAND, 
276                                         esc_step_from=10, esc_step_to=10, 
277                                         esc_period=0,
278                                         shortdata="",
279                                         longdata="%s:/usr/share/monitor-server/checkslices.py {HOSTNAME} disablesite" % config.MONITOR_HOSTNAME, 
280                                         operationcondition_list=[ OperationConditionNotAck() ]),
281                                 ActionOperation(operationtype=defines.OPERATION_TYPE_MESSAGE, 
282                                         shortdata=mailtxt.nodedown_two_subject,
283                                         longdata=mailtxt.nodedown_two,
284                                         esc_step_from=10, esc_step_to=10, 
285                                         esc_period=0, 
286                                         object=defines.OPERATION_OBJECT_GROUP, 
287                                         objectid=site_user_group.usrgrpid, 
288                                         operationcondition_list=[ OperationConditionNotAck() ] ), 
289                                 ActionOperation(operationtype=defines.OPERATION_TYPE_MESSAGE, 
290                                         shortdata=mailtxt.nodedown_two_subject,
291                                         longdata=mailtxt.nodedown_two,
292                                         esc_step_from=14, esc_step_to=14, 
293                                         esc_period=0, 
294                                         object=defines.OPERATION_OBJECT_GROUP, 
295                                         objectid=site_user_group.usrgrpid, 
296                                         operationcondition_list=[ OperationConditionNotAck() ] ), 
297
298                                 # STAGE 3
299                                 ActionOperation(operationtype=defines.OPERATION_TYPE_COMMAND, 
300                                         esc_step_from=17, esc_step_to=17, 
301                                         esc_period=0, 
302                                         shortdata="",
303                                         longdata="%s:/usr/share/monitor-server/checkslices.py {HOSTNAME} disableslices" % config.MONITOR_HOSTNAME, 
304                                         # TODO: send notice to users of slices
305                                         operationcondition_list=[ OperationConditionNotAck() ]),
306                                 ActionOperation(operationtype=defines.OPERATION_TYPE_MESSAGE, 
307                                         shortdata=mailtxt.nodedown_three_subject,
308                                         longdata=mailtxt.nodedown_three,
309                                         esc_step_from=17, esc_step_to=17, 
310                                         esc_period=0, 
311                                         object=defines.OPERATION_OBJECT_GROUP, 
312                                         objectid=site_user_group.usrgrpid, 
313                                         operationcondition_list=[ OperationConditionNotAck() ] ), 
314                                 # STAGE 4++
315                                 ActionOperation(operationtype=defines.OPERATION_TYPE_COMMAND, 
316                                         esc_step_from=21, esc_step_to=0, 
317                                         esc_period=int(BI_WEEKLY_ESC_PERIOD*3.5),
318                                         shortdata="",
319                                         longdata="%s:/usr/share/monitor-server/checkslices.py {HOSTNAME} forever" % config.MONITOR_HOSTNAME, 
320                                         operationcondition_list=[ OperationConditionNotAck() ]),
321                                 ActionOperation(operationtype=defines.OPERATION_TYPE_MESSAGE, 
322                                         shortdata=mailtxt.nodedown_four_subject,
323                                         longdata=mailtxt.nodedown_four,
324                                         esc_step_from=21, esc_step_to=0, 
325                                         esc_period=int(BI_WEEKLY_ESC_PERIOD*3.5),
326                                         object=defines.OPERATION_OBJECT_GROUP, 
327                                         objectid=site_user_group.usrgrpid, 
328                                         operationcondition_list=[ OperationConditionNotAck() ] ), 
329                         ]
330
331 if __name__ == "__main__":
332         setup_global()
333         session.flush()