fixed the httpd conf issue with redirecting to /monitor/
authorStephen Soltesz <soltesz@cs.princeton.edu>
Thu, 4 Dec 2008 22:21:20 +0000 (22:21 +0000)
committerStephen Soltesz <soltesz@cs.princeton.edu>
Thu, 4 Dec 2008 22:21:20 +0000 (22:21 +0000)
added styles for severity levels on node actions from zabbix
added extra class definitions to zabbixapi/model.py for event queries
added ack'd/non-ack'd action view based on zabbix db.

monitor-server.init
monitor/database/dborm.py
monitor/database/zabbixapi/model.py
web/MonitorWeb/monitorweb/commands.py
web/MonitorWeb/monitorweb/controllers.py
web/MonitorWeb/monitorweb/static/css/style.css
web/MonitorWeb/monitorweb/templates/master.kid

index 098ecba..28a7df8 100644 (file)
@@ -242,50 +242,33 @@ function create_httpd_conf ()
                WROTE_HTTP_CONFIG="true"
        fi
 
                WROTE_HTTP_CONFIG="true"
        fi
 
-       # TODO: make http port configurable.
+       # TODO: support HTTPS as well as port 80.  currently not specifying port
+       #               80 breaks https for other content on the myplc.
        # TODO: make proxy port configurable.
 
        cat <<EOF > ${MONITOR_HTTP_CONF}
        # TODO: make proxy port configurable.
 
        cat <<EOF > ${MONITOR_HTTP_CONF}
-NameVirtualHost *
-
-<VirtualHost *>
-    ServerName ${PLC_MONITOR_HOST}
-    ServerAdmin ${PLC_MONITOR_EMAIL}
-    UseCanonicalName Off
-    ServerSignature Off
-
-       # NOTE: this appears to alter the global document root, for port 80...
-       #  not sure if it's possible to serve two different 'virtualhosts' from
-       #  the same port and same hostname with different document roots...
-    #DocumentRoot ${MONITORPATH}/web/MonitorWeb/monitorweb
-
-    #<Directory "${MONITORPATH}/web/MonitorWeb/monitorweb">
-    #    Options Indexes FollowSymLinks
-    #    AllowOverride None
-    #    Order allow,deny
-    #    Allow from all
-    #</Directory>
 
 
-    #LogLevel debug
-    Errorlog /var/log/httpd/monitorwebapp-error_log
-    Customlog /var/log/httpd/monitorwebapp-access_log common
-
-    AddDefaultCharset utf-8
+# NOTE: I've tried other means of redirection, including mod_rewrite, but did
+#      not have any success.  The means below is not idea, b/c it does not keep
+#      non-ssl session as non-ssl.  But it works.
 
 
-    #NOTE: This doesn't work as expected.
-    #  Load everything out of the DocumentRoot that is static
-    #  ProxyPass /monitor/static !
+# NOTE: redirect path without trailing '/' to path with.  Favor SSL.
+Redirect /monitor https://${MONITOR_HOSTNAME}:${PLC_WWW_SSL_PORT}/monitor/
 
 
-    ProxyPass /tg_js http://127.0.0.1:8080/tg_js
-    ProxyPassReverse /tg_js http://127.0.0.1:8080/tg_js
-
-    ProxyPass /monitor http://127.0.0.1:8080
-    ProxyPassReverse /monitor http://127.0.0.1:8080
+# NOTE: this directive strips '/monitor/' from the requested path and pastes
+#       the remaining part to the end of the ProxyPass url below.  All TG urls
+#       should be relative to their current position, or the absolute path
+#       that includes /monitor/ at the beginning.  
+# TODO: make location configurable.
+<Location '/monitor/'>
+    #LogLevel debug
+    #Errorlog /var/log/httpd/monitorwebapp-error_log
+    #Customlog /var/log/httpd/monitorwebapp-access_log common
 
 
-    ProxyPreserveHost On
-    ProxyRequests Off
+    ProxyPass http://127.0.0.1:8080/
+    ProxyPassReverse http://127.0.0.1:8080/
+</Location>
 
 
-</VirtualHost>
 EOF
 }
 
 EOF
 }
 
@@ -296,6 +279,14 @@ function start_tg_server ()
        popd
 }
 
        popd
 }
 
+function stop_tg_server ()
+{
+        pid=$( cat /var/run/monitorweb.pid )
+        if [ -n "$pid" ] ; then
+                kill $pid
+        fi
+}
+
 function check_zab_server ()
 {
        ZABBIXCFG=/etc/zabbix
 function check_zab_server ()
 {
        ZABBIXCFG=/etc/zabbix
@@ -306,7 +297,7 @@ function check_zab_server ()
                    -e "s#DBName=.*#DBName=$ZABBIX_DB_NAME#g" \
                    -e "s#DBUser=.*#DBUser=$ZABBIX_DB_USER#g" \
                    -e "s#DBPassword=.*#DBPassword=$PLC_MONITOR_DBPASSWORD#g" \
                    -e "s#DBName=.*#DBName=$ZABBIX_DB_NAME#g" \
                    -e "s#DBUser=.*#DBUser=$ZABBIX_DB_USER#g" \
                    -e "s#DBPassword=.*#DBPassword=$PLC_MONITOR_DBPASSWORD#g" \
-                   -e "s/.*ExternalScripts=.*/ExternalScripts=${MONITORPATH}\/zabbix/g" \
+                   -e "s#.*ExternalScripts=.*#ExternalScripts=${MONITORPATH}/zabbix#g" \
                    ${ZABBIXCFG}/zabbix_server.conf > $TMP_FILE
                cat $TMP_FILE > ${ZABBIXCFG}/zabbix_server.conf
        fi
                    ${ZABBIXCFG}/zabbix_server.conf > $TMP_FILE
                cat $TMP_FILE > ${ZABBIXCFG}/zabbix_server.conf
        fi
@@ -418,6 +409,7 @@ case "$1" in
                MESSAGE=$"Stopping Monitor"
                dialog "$MESSAGE"
 
                MESSAGE=$"Stopping Monitor"
                dialog "$MESSAGE"
 
+               stop_tg_server
                service zabbix_server stop
                service zabbix_agentd stop
                # TODO: is there anything to stop?
                service zabbix_server stop
                service zabbix_agentd stop
                # TODO: is there anything to stop?
index 5e54f11..687881a 100644 (file)
@@ -9,3 +9,4 @@ mon_session = sqlalchemy.orm.scoped_session(sqlalchemy.orm.sessionmaker(autoflus
 zab_metadata = sqlalchemy.MetaData()
 zab_metadata.bind = sqlalchemy.create_engine(config.zabbix_dburi, echo=config.echo)
 zab_session = sqlalchemy.orm.scoped_session(sqlalchemy.orm.sessionmaker(autoflush=False,autocommit=True))
 zab_metadata = sqlalchemy.MetaData()
 zab_metadata.bind = sqlalchemy.create_engine(config.zabbix_dburi, echo=config.echo)
 zab_session = sqlalchemy.orm.scoped_session(sqlalchemy.orm.sessionmaker(autoflush=False,autocommit=True))
+zab_session.bind = zab_metadata.bind
index 3d6bd40..35784e6 100644 (file)
@@ -422,6 +422,42 @@ class IDs(Entity):
                autoload=True,
        )
 
                autoload=True,
        )
 
+class Escalation(ZabbixEntity):
+       using_options(
+               tablename='escalations',
+               autoload=True,
+               auto_primarykey='escalationid'
+       )
+
+class Event(ZabbixEntity):
+       using_options(
+               tablename='events',
+               autoload=True,
+               auto_primarykey='eventid'
+       )
+
+class Item(ZabbixEntity):
+       using_options(
+               tablename='items',
+               autoload=True,
+               auto_primarykey='itemid'
+       )
+
+class Acknowledge(ZabbixEntity):
+       using_options(
+               tablename='acknowledges',
+               autoload=True,
+               auto_primarykey='acknowledgeid'
+       )
+
+class Trigger(ZabbixEntity):
+       using_options(
+               tablename='triggers',
+               autoload=True,
+               auto_primarykey='triggerid'
+       )
+       
+
 class Right(ZabbixEntity):
        # rights of a usergroup to interact with hosts of a hostgroup
        using_options(
 class Right(ZabbixEntity):
        # rights of a usergroup to interact with hosts of a hostgroup
        using_options(
index 9e75f08..68df39c 100644 (file)
@@ -2,7 +2,7 @@
 """This module contains functions called from console script entry points."""\r
 \r
 import sys\r
 """This module contains functions called from console script entry points."""\r
 \r
 import sys\r
-from os import getcwd\r
+from os import getcwd, getpid\r
 from os.path import dirname, exists, join\r
 \r
 import pkg_resources\r
 from os.path import dirname, exists, join\r
 \r
 import pkg_resources\r
@@ -45,6 +45,11 @@ def start():
         except pkg_resources.DistributionNotFound:\r
             raise ConfigurationError("Could not find default configuration.")\r
 \r
         except pkg_resources.DistributionNotFound:\r
             raise ConfigurationError("Could not find default configuration.")\r
 \r
+       if "prod" in configfile:\r
+               f = open("/var/run/monitorweb.pid", 'w')\r
+               f.write(str(getpid()))\r
+               f.close()\r
+\r
     turbogears.update_config(configfile=configfile,\r
         modulename="monitorweb.config")\r
 \r
     turbogears.update_config(configfile=configfile,\r
         modulename="monitorweb.config")\r
 \r
index db3fbd8..be94316 100644 (file)
@@ -3,9 +3,15 @@ from turbogears import controllers, expose, flash
 # from monitorweb import model
 # import logging
 # log = logging.getLogger("monitorweb.controllers")
 # from monitorweb import model
 # import logging
 # log = logging.getLogger("monitorweb.controllers")
+import re
 from monitor.database.info.model import *
 from monitor.database.info.model import *
+from monitor.database.zabbixapi.model import *
+from monitor.database.dborm import zab_session as session
+from monitor.database.dborm import zab_metadata as metadata
+
 from pcucontrol import reboot
 from monitor.wrapper.plccache import plcdb_id2lb as site_id2lb
 from pcucontrol import reboot
 from monitor.wrapper.plccache import plcdb_id2lb as site_id2lb
+from monitor.wrapper.plccache import plcdb_hn2lb as site_hn2lb
 
 def format_ports(pcu):
        retval = []
 
 def format_ports(pcu):
        retval = []
@@ -169,7 +175,66 @@ class Root(controllers.RootController):
                                
                return dict(query=query, fc=filtercount)
 
                                
                return dict(query=query, fc=filtercount)
 
-       @expose(template="monitorweb.templates.pculist")
+       @expose(template="monitorweb.templates.actionlist")
        def action(self, filter='all'):
        def action(self, filter='all'):
-               filtercount = {'ok' : 0, 'NetDown': 0, 'Not_Run' : 0, 'pending' : 0, 'all' : 0}
-               return dict(query=[], fc=filtercount)
+               session.bind = metadata.bind
+               filtercount = {'active' : 0, 'acknowledged': 0, 'all' : 0}
+               # With Acknowledgement
+               sql_ack = 'SELECT DISTINCT h.host,t.description,t.priority,t.lastchange,a.message '+ \
+              ' FROM triggers t,hosts h,items i,functions f, hosts_groups hg,escalations e,acknowledges a ' + \
+              ' WHERE f.itemid=i.itemid ' + \
+                  ' AND h.hostid=i.hostid ' + \
+                  ' AND hg.hostid=h.hostid ' + \
+                  ' AND t.triggerid=f.triggerid ' + \
+                  ' AND t.triggerid=e.triggerid ' + \
+                  ' AND a.eventid=e.eventid ' + \
+                  ' AND t.status=' + str(defines.TRIGGER_STATUS_ENABLED) + \
+                  ' AND i.status=' + str(defines.ITEM_STATUS_ACTIVE) + \
+                  ' AND h.status=' + str(defines.HOST_STATUS_MONITORED) + \
+                  ' AND t.value=' + str(defines.TRIGGER_VALUE_TRUE) + \
+              ' ORDER BY t.lastchange DESC';
+
+               # WithOUT Acknowledgement
+               sql_noack = 'SELECT DISTINCT h.host,t.description,t.priority,t.lastchange,e.eventid ' + \
+              ' FROM triggers t,hosts h,items i,functions f, hosts_groups hg,escalations e,acknowledges a ' + \
+              ' WHERE f.itemid=i.itemid ' + \
+                  ' AND h.hostid=i.hostid ' + \
+                  ' AND hg.hostid=h.hostid ' + \
+                  ' AND t.triggerid=f.triggerid ' + \
+                  ' AND t.triggerid=e.triggerid ' + \
+                  ' AND e.eventid not in (select eventid from acknowledges) ' + \
+                  ' AND t.status=' + str(defines.TRIGGER_STATUS_ENABLED) + \
+                  ' AND i.status=' + str(defines.ITEM_STATUS_ACTIVE) + \
+                  ' AND h.status=' + str(defines.HOST_STATUS_MONITORED) + \
+                  ' AND t.value=' + str(defines.TRIGGER_VALUE_TRUE) + \
+              ' ORDER BY t.lastchange DESC';
+               # for i in session.execute(sql): print i
+
+               query=[]
+               replace = re.compile(' {.*}')
+               for sql,ack in [(sql_ack,True), (sql_noack,False)]:
+                       result = session.execute(sql)
+                       for row in result:
+                               try:
+                                       newrow = [ site_hn2lb[row[0].lower()] ] + [ r for r in row ]
+                               except:
+                                       print site_hn2lb.keys()
+                                       newrow = [ "unknown" ] + [ r for r in row ]
+
+                               newrow[2] = replace.sub("", newrow[2]) # strip {.*} expressions
+
+                               # NOTE: filter count
+                               filtercount['all'] += 1
+                               if not ack: # for unacknowledged
+                                       filtercount['active'] += 1
+                                       if filter == 'active':
+                                               query.append(newrow)
+                               else:
+                                       filtercount['acknowledged'] += 1
+                                       if filter == 'acknowledged':
+                                               query.append(newrow)
+                                       
+                               if filter != "acknowledged" and filter != "active":
+                                       query.append(newrow)
+
+               return dict(query=query, fc=filtercount)
index 072c484..60c902e 100644 (file)
@@ -50,6 +50,13 @@ a.link, a, a.active {
 #site-good { background-color : darkseagreen; }\r
 #site-down { background-color: indianred; }\r
 \r
 #site-good { background-color : darkseagreen; }\r
 #site-down { background-color: indianred; }\r
 \r
+#severity-0     {   background-color: #AADDAA;  }\r
+#severity-1     {   background-color: #CCE2CC;  }\r
+#severity-2     {   background-color: #EFEFCC;  }\r
+#severity-3     {   background-color: #DDAAAA;  }\r
+#severity-4     {   background-color: #FF8888;  }\r
+#severity-5     {   background-color: #FF0000;  }\r
+\r
 /*#nps-table { background-color: lightgrey; }*/\r
 /*#sub-table { background-color: lightgrey; }*/\r
 /* td, th {padding:2px;border:none;} */\r
 /*#nps-table { background-color: lightgrey; }*/\r
 /*#sub-table { background-color: lightgrey; }*/\r
 /* td, th {padding:2px;border:none;} */\r
index ba39836..017b72a 100644 (file)
@@ -15,8 +15,7 @@
             text-align: right;\r
         }\r
     </style>\r
             text-align: right;\r
         }\r
     </style>\r
-    <link rel="stylesheet" type="text/css" media="screen" href="../static/css/style.css"\r
-        py:attrs="href=tg.url('/static/css/style.css')"/>\r
+    <link rel="stylesheet" type="text/css" media="screen" href="${tg.url('static/css/style.css')}"/>\r
 </head>\r
 \r
 <body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()">\r
 </head>\r
 \r
 <body py:match="item.tag=='{http://www.w3.org/1999/xhtml}body'" py:attrs="item.items()">\r