break apart init scripts for monitor, zabbix, and rt3
Stephen Soltesz [Sat, 20 Jun 2009 21:54:47 +0000 (21:54 +0000)]
add a monitor-rt rpm package
add templates for rt configs

Monitor.spec
monitor-server.init
monitor.functions [new file with mode: 0644]
rt3/RT_SiteConfig.pm [new file with mode: 0644]
rt3/initialdata [new file with mode: 0644]
rt3/monitor-rt3.init [new file with mode: 0644]
web/MonitorWeb/monitorweb/templates/actionsummary.kid [new file with mode: 0644]
zabbix/monitor-zabbix.init [new file with mode: 0644]

index 3ec4ead..97a9e39 100644 (file)
@@ -90,6 +90,19 @@ The server side include all python modules and scripts needed to fully
 operation, track, and interact with any third-party monitoring software, such
 as Zabbix DB.
 
+######################################## RT setup
+
+%package rt
+summary: Dependencies and default configuration for RT3
+group: applications/system
+Requires: monitor-server
+Requires: rt3
+Requires: rt3-mailgate
+
+%description
+RT3 is a ticket tracking system.  This RPM integrates RT into the MyOps
+framework, and MyPLC in general.
+
 ######################################## PCU Control
 
 %package pcucontrol
@@ -139,7 +152,10 @@ install -d $RPM_BUILD_ROOT/var/lib/%{name}/archive-pdb
 install -d $RPM_BUILD_ROOT/var/www/cgi-bin/monitor/
 install -d $RPM_BUILD_ROOT/var/www/html/monitorlog/
 
+install -D -m 644 monitor.functions $RPM_BUILD_ROOT/%{_sysconfdir}/plc.d/monitor.functions
 install -D -m 755 monitor-server.init $RPM_BUILD_ROOT/%{_sysconfdir}/plc.d/monitor
+install -D -m 755 zabbix/monitor-zabbix.init $RPM_BUILD_ROOT/%{_sysconfdir}/plc.d/zabbix
+install -D -m 755 rt3/monitor-rt3.init $RPM_BUILD_ROOT/%{_sysconfdir}/plc.d/rt3
 
 echo " * Installing core scripts"
 rsync -a --exclude www --exclude archive-pdb --exclude .svn --exclude CVS \
@@ -203,6 +219,10 @@ rm -rf $RPM_BUILD_ROOT
 %{_initrddir}/monitor
 %{_sysconfdir}/cron.d/monitor
 
+%files rt 
+%defattr(-,root,root)
+/usr/share/%{name}/rt3
+
 %files pcucontrol
 %{python_sitearch}/pcucontrol
 
@@ -216,9 +236,6 @@ rm -rf $RPM_BUILD_ROOT
 #easy_install --build-directory /var/tmp -UZ ElementTree
 ##easy_install --build-directory /var/tmp -UZ http://pypi.python.org/packages/2.5/E/Extremes/Extremes-1.1-py2.5.egg
 
-# NOTE: enable monitor by default, since we're installing it.
-plc-config --save /etc/planetlab/default_config.xml \
-                       --category plc_monitor --variable enabled --value true
 
 ## TODO: something is bad wrong with this approach.
 easy_install --build-directory /var/tmp -UZ http://files.turbogears.org/eggs/TurboGears-1.0.7-py2.5.egg
@@ -238,6 +255,13 @@ if ! grep '<category id="plc_monitor">' /etc/planetlab/default_config.xml ; then
     sed -i 's|<category id="plc_net">| <category id="plc_monitor">\n <name>Monitor Service Configuration</name>\n <description>Monitor</description>\n <variablelist>\n <variable id="enabled" type="boolean">\n <name>Enabled</name>\n <value>true</value>\n <description>Enable on this machine.</description>\n </variable>\n <variable id="email">\n <value></value>\n </variable>\n <variable id="dbpassword">\n <value></value>\n </variable>\n <variable id="host" type="hostname">\n <name>Hostname</name>\n <value>pl-virtual-06.cs.princeton.edu</value>\n <description>The fully qualified hostname.</description>\n </variable>\n <variable id="ip" type="ip">\n <name>IP Address</name>\n <value/>\n <description>The IP address of the monitor server.</description>\n </variable>\n </variablelist>\n </category>\n <category id="plc_net">|' /etc/planetlab/default_config.xml
 fi
 
+# NOTE: enable monitor by default, since we're installing it.
+plc-config --save /etc/planetlab/default_config.xml \
+                       --category plc_monitor --variable enabled --value true
+
+%post rt
+plc-config --save /etc/planetlab/default_config.xml \
+                       --category plc_rt --variable enabled --value true
 
 %post server
 # TODO: this will be nice when we have a web-based service running., such as
index 6817b6a..cc7e143 100644 (file)
@@ -30,9 +30,6 @@ pghba_conf=$PGDATA/pg_hba.conf
 export PGPORT=$PLC_DB_PORT
 
 
-ZABBIX_DB_USER="zabbixuser"
-ZABBIX_DB_NAME="zabbix"
-
 MONITOR_DB_USER="monitoruser"
 MONITOR_DB_NAME="monitor"
 
@@ -42,123 +39,16 @@ if [ -z "$PLC_MONITOR_IP" ] ; then
        PLC_MONITOR_IP=$( gethostbyname $PLC_MONITOR_HOST )
 fi
 
-function check_pg_hba ()
-{
-       NAME=$1
-       USER=$2
-       #### SETUP ACCESS to this user and database
-       mkdir -p $PGDATA/pg_hba.conf.d
-       CONF=$PGDATA/pg_hba.conf.d/${NAME}.conf
-       if [ ! -f $CONF ] ; then
-               echo "host $NAME $USER 127.0.0.1/32 password"   > $CONF
-               echo "host $NAME $USER $PLC_MONITOR_IP/32 password" >> $CONF
-
-               WROTE_PG_CONFIG="true"
-       fi
-}
-
-function check_user_and_db()
-{
-    CREATED=
-       NAME=$1
-       USER=$2
-    # confirm user is present or create it
-    user_present=$( psql -U postgres -c "select * from pg_user;" -d template1 | grep $USER )
-    if [ -z $user_present ] ; then 
-        createuser --no-superuser --no-createdb --no-createrole --login --unencrypted --echo $USER -U postgres
-               CREATED="true"
-    fi
-    
-    # confirm database is present or create it
-    db_present=$( psql -U postgres -c "select * from pg_database;" -d template1 | grep $NAME )
-    if [ -z $db_present ] ; then
-        createdb --owner=$USER $NAME -U postgres
-               CREATED="true"
-    fi
-
-    # Create/update the unprivileged database user and password
-    if [[ -z "$PLC_MONITOR_DBPASSWORD" || "$PLC_MONITOR_DBPASSWORD" = "None" ]] ; then
-        # Zabbix doesn't like plain uuidgen passwords
-        PLC_MONITOR_DBPASSWORD=$( uuidgen | md5sum - | awk '{print $1}' )
-        plc-config --category=plc_monitor --variable=dbpassword --value="$PLC_MONITOR_DBPASSWORD" --save=$local_config $local_config
-        service plc reload
-               CREATED="true"
-    fi
-    if [ -n "$CREATED" ] ; then
-        psql -d template1 -U postgres -c "ALTER USER $USER WITH PASSWORD '$PLC_MONITOR_DBPASSWORD';"
-    fi
-}
-
-function if_present_load ()
-{
-    file=$1
-    if [ -f $file ] ; then
-        psql -d $ZABBIX_DB_NAME -U $ZABBIX_DB_USER < $file
-    fi
-}
 function check_monitor_schema_and_data() 
 {
        # NOTE: call create_all() to setup the database from the info model.
        python -c "from monitor.database.info.model import *; from elixir import create_all; create_all()"
 }
 
-function check_zabbix_schema_and_data() 
-{
-    schema_present=$( psql -U $ZABBIX_DB_USER $ZABBIX_DB_NAME -c "\d;" < /dev/null | grep hosts )
-    if [ -z $schema_present ] ; then
-        echo "... initial import can take SEVERAL minutes. please wait ..."
-        if_present_load "/usr/local/zabbix/misc/create/schema/postgresql.sql"
-        if_present_load "/usr/local/zabbix/misc/create/data/data.sql"
-        if_present_load "/usr/local/zabbix/misc/create/data/images_pgsql.sql"
-       ## TODO: update ZABBIX Server entry, "update hosts set status=0, host='MyPLC Server' where hostid=10017"
-    fi
-}
-
-function check_zabbix_templates_and_import ()
-{
-       # LOG IN
-       COOKIE_FILE=/tmp/cookiejar.txt
-       rm -f ${COOKIE_FILE}
-       TEMPLATES_DIR=${MONITORPATH}/zabbix/templates
-       curl -s --cookie $COOKIE_FILE --cookie-jar $COOKIE_FILE \
-                       --form "enter=Enter" \
-                       --form "name=Admin" \
-                       --form "password=zabbix" \
-                       "http://${PLC_MONITOR_HOST}/zabbix/index.php?login=1"
-       
-       deleted=$( grep 'deleted' $COOKIE_FILE )
-       if [ -n "$deleted" ] ; then
-               echo "Login to the zabbix web server failed!!!"
-               return 1
-       fi
-
-       for file in ${TEMPLATES_DIR}/*.xml ; do 
-               # 0 - update , 1 - skip, 0 - add
-               echo "############### IMPORTING $file" >> /var/log/monitor.log
-               curl -s --cookie $COOKIE_FILE --cookie-jar $COOKIE_FILE \
-                       --form "config=1" \
-                       --form "import_file=@${file}" \
-                       --form "rules[host][exist]=0" \
-                       --form "rules[host][missed]=0" \
-                       --form "rules[template][exist]=0" \
-                       --form "rules[template][missed]=1" \
-                       --form "rules[item][exist]=0" \
-                       --form "rules[item][missed]=0" \
-                       --form "rules[trigger][exist]=0" \
-                       --form "rules[trigger][missed]=0" \
-                       --form "rules[graph][exist]=0" \
-                       --form "rules[graph][missed]=0" \
-                       --form "import=Import" \
-                       "http://${PLC_MONITOR_HOST}/zabbix/exp_imp.php" >> /var/log/monitor.log
-       done
-}
-
-
 function check_monitor_conf ()
 {
        MONITOR_CONFIG=/etc/monitor.conf
 
-
        # Using plcsh add default, monitor user
        plcsh <<EOF &>/dev/null 
 AddPerson({'first_name' : 'Monitor', 'last_name' : 'Server', 'password' : '${PLC_MONITOR_DBPASSWORD}', 'email' : '${PLC_MONITOR_EMAIL}'})
@@ -293,63 +183,6 @@ function stop_tg_server ()
         fi
 }
 
-function check_zab_server ()
-{
-       ZABBIXCFG=/etc/zabbix
-       TMP_FILE=`mktemp /tmp/zbxtmpXXXXXX`
-
-       if [ -f ${ZABBIXCFG}/zabbix_server.conf ] ; then
-               sed -e "s/#DBHost=.*/DBHost=$PLC_MONITOR_HOST/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" \
-                   ${ZABBIXCFG}/zabbix_server.conf > $TMP_FILE
-               cat $TMP_FILE > ${ZABBIXCFG}/zabbix_server.conf
-       fi
-       service zabbix_server start
-       rm -f $TMP_FILE
-
-}
-function check_zab_agentd ()
-{
-       ZABBIXCFG=/etc/zabbix
-       TMP_FILE=`mktemp /tmp/zbxtmpXXXXXX`
-       if [ -f ${ZABBIXCFG}/zabbix_agentd.conf ] ; then
-               HOST=`hostname`
-               sed -e "s#Server=.*#Server=$PLC_MONITOR_HOST#g" \
-                   -e "s#Hostname=.*#Hostname=$HOST#g" \
-                   ${ZABBIXCFG}/zabbix_agentd.conf > $TMP_FILE
-               cat $TMP_FILE > ${ZABBIXCFG}/zabbix_agentd.conf 
-       fi
-       service zabbix_agentd start
-       rm -f $TMP_FILE
-}
-function check_zab_webconfig()
-{
-       # SETUP zabbix gui configuration
-       ZABBIX_WEB_CFG=/var/www/html/zabbix/conf/zabbix.conf.php 
-       if [ ! -f $ZABBIX_WEB_CFG ] ; then
-               touch  $ZABBIX_WEB_CFG
-               cat <<EOF > $ZABBIX_WEB_CFG
-<?php
-global \$DB;
-
-\$DB["TYPE"]           = "POSTGRESQL";
-\$DB["SERVER"]         = "localhost";
-\$DB["PORT"]           = "0";
-\$DB["DATABASE"]               = "$ZABBIX_DB_NAME";
-\$DB["USER"]           = "$ZABBIX_DB_USER";
-\$DB["PASSWORD"]               = "$PLC_MONITOR_DBPASSWORD";
-\$ZBX_SERVER           = "$PLC_MONITOR_HOST";
-\$ZBX_SERVER_PORT      = "10051";
-\$IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG;
-?>
-EOF
-               chmod 644 $ZABBIX_WEB_CFG
-       fi
-}
-
 if [ "$PLC_MONITOR_ENABLED" != "1" ] ; then
     exit 0
 fi
@@ -365,9 +198,6 @@ case "$1" in
                # WRITE default /etc/monitor.conf
                check_monitor_conf
 
-               #check_pg_hba $ZABBIX_DB_NAME $ZABBIX_DB_USER
-               #check_user_and_db $ZABBIX_DB_NAME $ZABBIX_DB_USER
-
                if [ -n "$WROTE_PG_CONFIG" ] ; then
                        # NOTE: restart db to enable access by users granted above.
                        service plc restart postgresql
@@ -378,10 +208,6 @@ case "$1" in
 
                check_monitor_schema_and_data
 
-               #check_zabbix_schema_and_data
-               #check_zabbix_templates_and_import
-
-
                # create /etc/httpd/conf.d/monitorweb.conf
                create_httpd_conf
                if [ -n "$WROTE_HTTP_CONFIG" ] ; then
@@ -392,11 +218,6 @@ case "$1" in
                fi
                start_tg_server
 
-               # START zabbix services.  SETUP default config files.
-               #check_zab_server
-               #check_zab_agentd
-               #check_zab_webconfig
-
                result "$MESSAGE"
        ;;
 
@@ -410,30 +231,10 @@ case "$1" in
                result "$MESSAGE"
        ;;
 
-       sync)
-               MESSAGE=$"Syncing PLC db with Zabbix DB"
-               dialog "$MESSAGE"
-
-               # turn off zabbix server, etc. before writing to the db.
-               service plc stop monitor 
-
-               $MONITORPATH/zabbix/zabbixsync.py --setupids &> /var/log/monitor-server
-               $MONITORPATH/zabbix/zabbixsync.py --setupglobal 2>&1 >> /var/log/monitor-server
-               # import any templates
-               check_zabbix_templates_and_import
-
-               service plc start monitor 
-               
-               result "$MESSAGE"
-       ;;
-
        delete)
                MESSAGE=$"Deleting databases..."
                dialog "$MESSAGE"
 
-               #dropdb -U postgres $ZABBIX_DB_NAME
-               #dropuser -U postgres $ZABBIX_DB_USER
-
                dropdb -U postgres $MONITOR_DB_NAME
                dropuser -U postgres $MONITOR_DB_USER
 
@@ -445,9 +246,8 @@ case "$1" in
                dialog "$MESSAGE"
 
                stop_tg_server
-               #service zabbix_server stop
-               #service zabbix_agentd stop
-               # TODO: is there anything to stop?
+               # todo: disable cron entry?
+
                result "$MESSAGE"
        ;;
 esac
diff --git a/monitor.functions b/monitor.functions
new file mode 100644 (file)
index 0000000..4210e95
--- /dev/null
@@ -0,0 +1,89 @@
+#!/bin/bash
+#
+# priority: 850
+#
+# Manage settings for the Zabbix installtion and 
+#      other monitor-related things
+#
+# Stephen Soltesz <soltesz@cs.princeton.edu>
+# Copyright (C) 2008 The Trustees of Princeton University
+#
+# $Id$
+#
+
+# Source function library and configuration
+. /etc/plc.d/functions
+. /etc/planetlab/plc_config
+local_config=/etc/planetlab/configs/site.xml
+
+MONITORPATH=/usr/share/monitor
+
+# Be verbose
+set -x
+
+# Default locations
+PGDATA=/var/lib/pgsql/data
+postgresql_conf=$PGDATA/postgresql.conf
+pghba_conf=$PGDATA/pg_hba.conf
+
+# Export so that we do not have to specify -p to psql invocations
+export PGPORT=$PLC_DB_PORT
+
+WROTE_PG_CONFIG=
+
+if [ -z "$PLC_MONITOR_IP" ] ; then
+       PLC_MONITOR_IP=$( gethostbyname $PLC_MONITOR_HOST )
+fi
+
+function check_pg_hba ()
+{
+       NAME=$1
+       USER=$2
+       #### SETUP ACCESS to this user and database
+       mkdir -p $PGDATA/pg_hba.conf.d
+       CONF=$PGDATA/pg_hba.conf.d/${NAME}.conf
+       if [ ! -f $CONF ] ; then
+               echo "host $NAME $USER 127.0.0.1/32 password"   > $CONF
+               echo "host $NAME $USER $PLC_MONITOR_IP/32 password" >> $CONF
+
+               WROTE_PG_CONFIG="true"
+       fi
+}
+
+function check_user_and_db()
+{
+    CREATED=
+       NAME=$1
+       USER=$2
+    # confirm user is present or create it
+    user_present=$( psql -U postgres -c "select * from pg_user;" -d template1 | grep $USER )
+    if [ -z $user_present ] ; then 
+        createuser --no-superuser --no-createdb --no-createrole --login --unencrypted --echo $USER -U postgres
+               CREATED="true"
+    fi
+    
+    # confirm database is present or create it
+    db_present=$( psql -U postgres -c "select * from pg_database;" -d template1 | grep $NAME )
+    if [ -z $db_present ] ; then
+        createdb --owner=$USER $NAME -U postgres
+               CREATED="true"
+    fi
+
+    # Create/update the unprivileged database user and password
+    if [[ -z "$PLC_MONITOR_DBPASSWORD" || "$PLC_MONITOR_DBPASSWORD" = "None" ]] ; then
+        # Zabbix doesn't like plain uuidgen passwords
+        PLC_MONITOR_DBPASSWORD=$( uuidgen | md5sum - | awk '{print $1}' )
+        plc-config --category=plc_monitor --variable=dbpassword --value="$PLC_MONITOR_DBPASSWORD" --save=$local_config $local_config
+        service plc reload
+               CREATED="true"
+    fi
+    if [ -n "$CREATED" ] ; then
+        psql -d template1 -U postgres -c "ALTER USER $USER WITH PASSWORD '$PLC_MONITOR_DBPASSWORD';"
+    fi
+}
+function check_monitor_schema_and_data() 
+{
+       # NOTE: call create_all() to setup the database from the info model.
+       python -c "from monitor.database.info.model import *; from elixir import create_all; create_all()"
+}
+
diff --git a/rt3/RT_SiteConfig.pm b/rt3/RT_SiteConfig.pm
new file mode 100644 (file)
index 0000000..52b5e6a
--- /dev/null
@@ -0,0 +1,72 @@
+# Any configuration directives you include  here will override
+# RT's default configuration file, RT_Config.pm
+
+#Site Configurations
+
+#Name of the site
+Set($rtname, 'PLC_NAME');
+
+#Site's Organization
+Set($Organization , 'PLC_RT_HOSTNAME');
+
+#Main email address for contacting the Support Team
+Set($CorrespondAddress , 'support@PLC_RT_HOSTNAME');
+
+#Default destination email address for replies
+Set($CommentAddress , 'root@PLC_RT_HOSTNAME');
+
+#System administrator mail address
+Set($OwnerEmail , 'root@PLC_RT_HOSTNAME');
+
+#Maximum attachment size
+Set($MaxAttachmentSize , 10000000);
+
+#Database configurations
+
+#Type of database: Postgresql
+Set($DatabaseType , 'Pg'); # e.g. Pg or mysql
+
+#The name of the database user (inside the database)
+Set($DatabaseUser , 'RT_DB_USER');
+
+#Password the DatabaseUser should use to access the database
+Set($DatabasePassword , 'RT_DB_PASSWORD');
+
+#The name of the RT's database on your database server
+Set($DatabaseName , 'RT_DB_NAME');
+
+#Database host
+Set($DatabaseHost , 'localhost');
+
+#RT's Database host
+Set($DatabaseRTHost , 'localhost');
+
+#Webserver paramters
+
+#Web path, such as https://rt.domain/web_path
+Set($WebPath , "/rt3"); # e.g. Set($WebPath , "");
+
+#URL
+Set($WebBaseURL , "http://PLC_RT_HOSTNAME"); # Set($WebBaseURL , "http://rt.PLC_RT_HOSTNAME");
+
+#Adding plugins
+#Set(@Plugins,qw(RT::FM));
+
+#Tuning Up the RT Config
+
+#Log File
+Set($LogToFile , 'debug');
+Set($LogDir, '/var/log/rt3/');
+#rt_debug.log should be created and set to the correct owner(apache ownerand group)/permissions (-rw-r--r--)Set($LogToFileNamed , "rt_debug.log");
+
+#Notify requestor: True (1)
+Set($NotifyActor, 1);
+
+#Send a copy to RT owner: True
+Set($LoopsToRTOwner , 1);
+
+#Standard Support Email Address
+Set($RTAddressRegexp , '^support@PLC_RT_HOSTNAME$');
+
+
+1;
diff --git a/rt3/initialdata b/rt3/initialdata
new file mode 100644 (file)
index 0000000..b5d7837
--- /dev/null
@@ -0,0 +1,646 @@
+# Initial data for a fresh RT3 Installation.
+
+@Users = (
+    {  Name     => 'Nobody',
+       RealName => 'Nobody in particular',
+       Comments => 'Do not delete or modify this user. It is integral '
+         . 'to RT\'s internal data structures',
+       Privileged => '0', },
+
+    {  Name         => 'root',
+       Gecos        => 'root',
+       RealName     => 'Enoch Root',
+       Password     => 'password',
+       EmailAddress => "root\@localhost",
+       Comments     => 'SuperUser',
+       Privileged   => '1', } );
+
+@Groups = (
+    { Name        => '',
+      Type        => 'Everyone',                        # loc
+      Domain      => 'SystemInternal',
+      Instance    => '',
+      Description => 'Pseudogroup for internal use',    # loc
+    },
+    { Type        => 'Privileged',                      # loc
+      Domain      => 'SystemInternal',
+      Instance    => '',
+      Name        => '',
+      Description => 'Pseudogroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'Unprivileged',                    # loc
+      Domain      => 'SystemInternal',
+      Instance    => '',
+      Description => 'Pseudogroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'Owner',                               # loc
+      Domain      => 'RT::System-Role',
+      Instance    => '',
+      Description => 'SystemRolegroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'Requestor',                           # loc
+      Domain      => 'RT::System-Role',
+      Instance    => '',
+      Description => 'SystemRolegroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'Cc',                                  # loc
+      Domain      => 'RT::System-Role',
+      Instance    => '',
+      Description => 'SystemRolegroup for internal use',    # loc
+    },
+    { Name        => '',
+      Type        => 'AdminCc',                             # loc
+      Domain      => 'RT::System-Role',
+      Instance    => '',
+      Description => 'Pseudogroup for internal use',        # loc
+    }, );
+
+@Queues = ({ Name              => 'support',
+             Description       => 'Queue for general issues',
+             CorrespondAddress => 'support@PLC_RT_HOSTNAME',
+             CommentAddress    => '', },
+
+                  { Name              => 'monitor',
+             Description       => 'Queue for monitor',
+             CorrespondAddress => 'monitor@PLC_RT_HOSTNAME',
+             CommentAddress    => '', },
+
+                  { Name              => 'security',
+             Description       => 'Queue for security issues',
+             CorrespondAddress => 'security@PLC_RT_HOSTNAME',
+             CommentAddress    => '', },
+
+                  { Name              => 'legal',
+             Description       => 'Queue for legal issues',
+             CorrespondAddress => 'legal@PLC_RT_HOSTNAME',
+             CommentAddress    => '', },
+
+                  { Name              => 'General',
+             Description       => 'The default queue',
+             CorrespondAddress => "",
+             CommentAddress    => "", },
+
+           { Name        => '___Approvals',
+             Description => 'A system-internal queue for the approvals system',
+             Disabled    => 2, } );
+
+@ScripActions = (
+
+    {  Name        => 'Autoreply To Requestors',    # loc
+       Description =>
+'Always sends a message to the requestors independent of message sender' ,                                            # loc
+       ExecModule => 'Autoreply',
+       Argument   => 'Requestor' },
+    { Name        => 'Notify Requestors',                    # loc
+      Description => 'Sends a message to the requestors',    # loc
+      ExecModule  => 'Notify',
+      Argument    => 'Requestor' },
+    { Name        => 'Notify Owner as Comment',              # loc
+      Description => 'Sends mail to the owner',              # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'Owner' },
+    { Name        => 'Notify Owner',                         # loc
+      Description => 'Sends mail to the owner',              # loc
+      ExecModule  => 'Notify',
+      Argument    => 'Owner' },
+    { Name        => 'Notify Ccs as Comment',              # loc
+      Description => 'Sends mail to the Ccs as a comment', # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'Cc' },
+    { Name        => 'Notify Ccs',                                   # loc
+      Description => 'Sends mail to the Ccs',                        # loc
+      ExecModule  => 'Notify',
+      Argument    => 'Cc' },
+    { Name        => 'Notify AdminCcs as Comment',                        # loc
+      Description => 'Sends mail to the administrative Ccs as a comment', # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'AdminCc' },
+    { Name        => 'Notify AdminCcs',                                   # loc
+      Description => 'Sends mail to the administrative Ccs',              # loc
+      ExecModule  => 'Notify',
+      Argument    => 'AdminCc' },
+
+    { Name        => 'Notify Requestors and Ccs as Comment',              # loc
+      Description => 'Send mail to requestors and Ccs as a comment',      # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'Requestor,Cc' },
+
+    { Name        => 'Notify Requestors and Ccs',                         # loc
+      Description => 'Send mail to requestors and Ccs',                   # loc
+      ExecModule  => 'Notify',
+      Argument    => 'Requestor,Cc' },
+
+    { Name        => 'Notify Requestors, Ccs and AdminCcs as Comment',    # loc
+      Description => 'Send mail to all watchers as a "comment"',          # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'All' },
+    { Name        => 'Notify Requestors, Ccs and AdminCcs',               # loc
+      Description => 'Send mail to all watchers',                         # loc
+      ExecModule  => 'Notify',
+      Argument    => 'All' },
+    { Name        => 'Notify Other Recipients as Comment',                # loc
+      Description => 'Sends mail to explicitly listed Ccs and Bccs',      # loc
+      ExecModule  => 'NotifyAsComment',
+      Argument    => 'OtherRecipients' },
+    { Name        => 'Notify Other Recipients',                           # loc
+      Description => 'Sends mail to explicitly listed Ccs and Bccs',      # loc
+      ExecModule  => 'Notify',
+      Argument    => 'OtherRecipients' },
+    { Name        => 'User Defined',                                      # loc
+      Description => 'Perform a user-defined action',                     # loc
+      ExecModule  => 'UserDefined', },
+    {  Name        => 'Create Tickets',                                    # loc
+       Description =>
+         'Create new tickets based on this scrip\'s template',             # loc
+       ExecModule => 'CreateTickets', },
+    { Name        => 'Open Tickets',
+      Description => 'Open tickets on correspondence',                    # loc
+      ExecModule  => 'AutoOpen' },
+);
+
+@ScripConditions = (
+    { Name                 => 'On Create',                                # loc
+      Description          => 'When a ticket is created',                 # loc
+      ApplicableTransTypes => 'Create',
+      ExecModule           => 'AnyTransaction', },
+
+    { Name                 => 'On Transaction',                           # loc
+      Description          => 'When anything happens',                    # loc
+      ApplicableTransTypes => 'Any',
+      ExecModule           => 'AnyTransaction', },
+    {
+
+      Name                 => 'On Correspond',                             # loc
+      Description          => 'Whenever correspondence comes in',          # loc
+      ApplicableTransTypes => 'Correspond',
+      ExecModule           => 'AnyTransaction', },
+
+    {
+
+      Name                 => 'On Comment',                                # loc
+      Description          => 'Whenever comments come in',                 # loc
+      ApplicableTransTypes => 'Comment',
+      ExecModule           => 'AnyTransaction' },
+    {
+
+      Name                 => 'On Status Change',                          # loc
+      Description          => 'Whenever a ticket\'s status changes',       # loc
+      ApplicableTransTypes => 'Status',
+      ExecModule           => 'AnyTransaction',
+
+    },
+    {
+
+      Name                 => 'On Priority Change',                       # loc
+      Description          => 'Whenever a ticket\'s priority changes',    # loc
+      ApplicableTransTypes => 'Set',
+      ExecModule           => 'PriorityChange',
+    },
+    {
+
+      Name                 => 'On Owner Change',                           # loc
+      Description          => 'Whenever a ticket\'s owner changes',        # loc
+      ApplicableTransTypes => 'Any',
+      ExecModule           => 'OwnerChange',
+
+    },
+    {
+
+      Name                 => 'On Queue Change',                           # loc
+      Description          => 'Whenever a ticket\'s queue changes',        # loc
+      ApplicableTransTypes => 'Set',
+      ExecModule           => 'QueueChange',
+
+    },
+    {  Name                 => 'On Resolve',                               # loc
+       Description          => 'Whenever a ticket is resolved',            # loc
+       ApplicableTransTypes => 'Status',
+       ExecModule           => 'StatusChange',
+       Argument             => 'resolved'
+
+    },
+
+    {  Name                 => 'User Defined',                             # loc
+       Description          => 'Whenever a user-defined condition occurs', # loc
+       ApplicableTransTypes => 'Any',
+       ExecModule           => 'UserDefined'
+
+    },
+
+);
+
+@Templates = (
+    { Queue       => '0',
+      Name        => 'Blank',                                             # loc
+      Description => 'A blank template',                                  # loc
+      Content     => '', },
+    {  Queue       => '0',
+       Name        => 'Autoreply',                                         # loc
+       Description => 'Default Autoresponse template',                     # loc
+       Content     => 'Subject: AutoReply: {$Ticket->Subject}
+
+
+Greetings,
+
+This message has been automatically generated in response to the
+creation of a trouble ticket regarding:
+       "{$Ticket->Subject()}", 
+a summary of which appears below.
+
+There is no need to reply to this message right now.  Your ticket has been
+assigned an ID of [{$rtname} #{$Ticket->id()}].
+
+Please include the string:
+
+         [{$rtname} #{$Ticket->id}]
+
+in the subject line of all future correspondence about this issue. To do so, 
+you may reply to this message.
+
+                        Thank you,
+                        {$Ticket->QueueObj->CorrespondAddress()}
+
+-------------------------------------------------------------------------
+{$Transaction->Content()}
+'
+    },
+
+    {  Queue       => '0',
+       Name        => 'Transaction',                     # loc
+       Description => 'Default transaction template',    # loc
+       Content     => 'RT-Attach-Message: yes
+
+
+{$Transaction->CreatedAsString}: Request {$Ticket->id} was acted upon.
+Transaction: {$Transaction->Description}
+       Queue: {$Ticket->QueueObj->Name}
+     Subject: {$Transaction->Subject || $Ticket->Subject || "(No subject given)"}
+       Owner: {$Ticket->OwnerObj->Name}
+  Requestors: {$Ticket->RequestorAddresses}
+      Status: {$Ticket->Status}
+ Ticket <URL: {$RT::WebURL}Ticket/Display.html?id={$Ticket->id} >
+
+
+{$Transaction->Content()}
+'
+    },
+
+    {
+
+      Queue       => '0',
+      Name        => 'Admin Correspondence',                     # loc
+      Description => 'Default admin correspondence template',    # loc
+      Content     => 'RT-Attach-Message: yes
+
+
+<URL: {$RT::WebURL}Ticket/Display.html?id={$Ticket->id} >
+
+{$Transaction->Content()}
+'
+    },
+
+    {  Queue       => '0',
+       Name        => 'Correspondence',                          # loc
+       Description => 'Default correspondence template',         # loc
+       Content     => 'RT-Attach-Message: yes
+
+{$Transaction->Content()}
+'
+    },
+
+    {  Queue       => '0',
+       Name        => 'Admin Comment',                           # loc
+       Description => 'Default admin comment template',          # loc
+       Content     =>
+'Subject: [Comment] {my $s=($Transaction->Subject||$Ticket->Subject); $s =~ s/\\[Comment\\]//g; $comment =~ s/^Re//i; $s;}
+
+
+{$RT::WebURL}Ticket/Display.html?id={$Ticket->id}
+This is a comment.  It is not sent to the Requestor(s):
+
+{$Transaction->Content()}
+'
+    },
+
+    {  Queue       => '0',
+       Name        => 'Status Change',                                     # loc
+       Description => 'Ticket status changed',                             # loc
+       Content     => 'Subject: Status Changed to: {$Transaction->NewValue}
+
+
+{$RT::WebURL}Ticket/Display.html?id={$Ticket->id}
+
+{$Transaction->Content()}
+'
+    },
+
+    {
+
+      Queue       => '0',
+      Name        => 'Resolved',                 # loc
+      Description => 'Ticket Resolved',          # loc
+      Content     => 'Subject: Resolved: {$Ticket->Subject}
+
+According to our records, your request has been resolved. If you have any
+further questions or concerns, please respond to this message.
+'
+    },
+    {  Queue       => '___Approvals',
+       Name        => "New Pending Approval",    # loc
+       Description =>
+         "Notify Owners and AdminCcs of new items pending their approval", # loc
+       Content => 'Subject: New Pending Approval: {$Ticket->Subject}
+
+Greetings,
+
+There is a new item pending your approval: "{$Ticket->Subject()}", 
+a summary of which appears below.
+
+Please visit {$RT::WebURL}Approvals/Display.html?id={$Ticket->id}
+to approve or reject this ticket, or {$RT::WebURL}Approvals/ to
+batch-process all your pending approvals.
+
+-------------------------------------------------------------------------
+{$Transaction->Content()}
+'
+    },
+    {  Queue       => '___Approvals',
+       Name        => "Approval Passed",    # loc
+       Description =>
+         "Notify Owner of their ticket has been approved by some approver", # loc
+       Content => 'Subject: Ticket Approved: {$Ticket->Subject}
+
+Greetings,
+
+Your ticket has been approved by { eval { $Approval->OwnerObj->Name } }.
+Other approvals may be pending.
+'
+    },
+    {  Queue       => '___Approvals',
+       Name        => "All Approvals Passed",    # loc
+       Description =>
+         "Notify Owner of their ticket has been approved by all approvers", # loc
+       Content => 'Subject: Ticket Approved: {$Ticket->Subject}
+
+Greetings,
+
+Your ticket has been approved.  Its Owner may now start to act on it.
+'
+    },
+    {  Queue       => '___Approvals',
+       Name        => "Approval Rejected",    # loc
+       Description =>
+         "Notify Owner of their rejected ticket", # loc
+       Content => 'Subject: Ticket Rejected: {$Ticket->Subject}
+
+Greetings,
+
+Your ticket has been rejected by { eval { $Approval->OwnerObj->Name } }.
+'
+    },
+);
+# }}}
+
+@Scrips = (
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Open Tickets',
+       Template       => 'Blank' },
+    {  ScripCondition => 'On Owner Change',
+       ScripAction    => 'Notify Owner',
+       Template       => 'Transaction' },
+    {  ScripCondition => 'On Create',
+       ScripAction    => 'AutoReply To Requestors',
+       Template       => 'AutoReply' },
+    {  ScripCondition => 'On Create',
+       ScripAction    => 'Notify AdminCcs',
+       Template       => 'Transaction' },
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Notify AdminCcs',
+       Template       => 'Admin Correspondence' },
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Notify Requestors And Ccs',
+       Template       => 'Correspondence' },
+    {  ScripCondition => 'On Correspond',
+       ScripAction    => 'Notify Other Recipients',
+       Template       => 'Correspondence' },
+    {  ScripCondition => 'On Comment',
+       ScripAction    => 'Notify AdminCcs As Comment',
+       Template       => 'Admin Comment' },
+    {  ScripCondition => 'On Comment',
+       ScripAction    => 'Notify Other Recipients As Comment',
+       Template       => 'Correspondence' },
+    {  ScripCondition => 'On Resolve',
+       ScripAction    => 'Notify Requestors',
+       Template       => 'Resolved' },
+    {  Description => "When an approval ticket is created, notify the Owner and AdminCc of the item awaiting their approval",    # loc
+       Queue          => '___Approvals',
+       ScripCondition => 'User Defined',
+       CustomIsApplicableCode => q[
+           $self->TicketObj->Type eq 'approval'        and
+           $self->TransactionObj->Field eq 'Status'    and
+           $self->TransactionObj->NewValue eq 'open'   and
+           eval { $T::Approving = ($self->TicketObj->AllDependedOnBy( Type => 'ticket' ))[0] }
+       ],
+       ScripAction    => 'Notify Owner',
+       Template       => 'New Pending Approval' },
+    {  Description => "If an approval is rejected, reject the original and delete pending approvals",    # loc
+       Queue            => '___Approvals',
+       ScripCondition   => 'On Status Change',
+       ScripAction      => 'User Defined',
+       CustomPrepareCode => q[
+# ------------------------------------------------------------------- #
+return(0) unless ( lc($self->TransactionObj->NewValue) eq "rejected" or
+                  lc($self->TransactionObj->NewValue) eq "deleted" );
+
+my $rejected = 0;
+my $links = $self->TicketObj->DependedOnBy;
+foreach my $link (@{ $links->ItemsArrayRef }) {
+    my $obj = $link->BaseObj;
+    if ($obj->QueueObj->IsActiveStatus($obj->Status)) {
+       if ($obj->Type eq 'ticket') {
+           $obj->Comment(
+               Content => $self->loc("Your request was rejected."),
+           );
+           $obj->SetStatus(
+               Status  => 'rejected',
+               Force   => 1,
+           );
+
+           $T::Approval = $self->TicketObj; # so we can access it inside templates
+           $self->{TicketObj} = $obj;  # we want the original id in the token line
+           $rejected = 1;
+       }
+       else {
+           $obj->SetStatus(
+               Status  => 'deleted',
+               Force   => 1,
+           );
+       }
+    }
+}
+
+$links = $self->TicketObj->DependsOn;
+foreach my $link (@{ $links->ItemsArrayRef }) {
+    my $obj = $link->TargetObj;
+    if ($obj->QueueObj->IsActiveStatus($obj->Status)) {
+       $obj->SetStatus(
+           Status      => 'deleted',
+           Force       => 1,
+       );
+    }
+}
+
+# Now magically turn myself into a Requestor Notify object...
+require RT::Action::Notify; bless($self, 'RT::Action::Notify');
+$self->{Argument} = 'Requestor'; $self->Prepare;
+
+return $rejected;
+# ------------------------------------------------------------------- #
+       ],
+       CustomCommitCode => '"never needed"',
+       Template          => 'Approval Rejected', },
+    {  Description => "When a ticket has been approved by any approver, add correspondence to the original ticket", # loc
+       Queue             => '___Approvals',
+       ScripCondition    => 'On Resolve',
+       ScripAction       => 'User Defined',
+       CustomPrepareCode => q[
+# ------------------------------------------------------------------- #
+return(0) unless ($self->TicketObj->Type eq 'approval');
+
+my $note;
+my $t = $self->TicketObj->Transactions;
+while (my $o = $t->Next) {
+    $note .= $o->Content . "\n" if $o->ContentObj
+           and $o->Content !~ /Default Approval/;
+}
+
+foreach my $obj ($self->TicketObj->AllDependedOnBy( Type => 'ticket' )) {
+    $obj->Comment(
+       Content => $self->loc( "Your request has been approved by [_1]. Other approvals may still be pending.", # loc
+           $self->TransactionObj->CreatorObj->Name,
+       ) . "\n" . $self->loc( "Approver's notes: [_1]", # loc
+           $note
+       ),
+    );
+    $T::Approval = $self->TicketObj; # so we can access it inside templates
+    $self->{TicketObj} = $obj;  # we want the original id in the token line
+}
+
+# Now magically turn myself into a Requestor Notify object...
+require RT::Action::Notify; bless($self, 'RT::Action::Notify');
+$self->{Argument} = 'Requestor'; $self->Prepare;
+
+return 1;
+# ------------------------------------------------------------------- #
+       ],
+       CustomCommitCode => '"never needed"',
+       Template => 'Approval Passed' },
+    {  Description => "When a ticket has been approved by all approvers, add correspondence to the original ticket", # loc
+       Queue             => '___Approvals',
+       ScripCondition    => 'On Resolve',
+       ScripAction       => 'User Defined',
+       CustomPrepareCode  => q[
+# ------------------------------------------------------------------- #
+# Find all the tickets that depend on this (that this is approving)
+
+my $Ticket = $self->TicketObj;
+my @TOP    = $Ticket->AllDependedOnBy( Type => 'ticket' );
+my $links  = $Ticket->DependedOnBy;
+my $passed = 0;
+
+while (my $link = $links->Next) {
+    my $obj = $link->BaseObj;
+    next if ($obj->HasUnresolvedDependencies( Type => 'approval' ));
+
+    if ($obj->Type eq 'ticket') {
+       $obj->Comment(
+           Content     => $self->loc("Your request has been approved."),
+       );
+       $T::Approval  = $Ticket;    # so we can access it inside templates
+       $self->{TicketObj} = $obj;  # we want the original id in the token line
+       $passed = 1;
+    }
+    elsif ($obj->Type eq 'approval') {
+       $obj->SetStatus( Status => 'open', Force => 1 );
+    }
+    elsif ($RT::UseCodeTickets and $obj->Type eq 'code') {
+       my $code = $obj->Transactions->First->Content;
+       my $rv;
+
+       foreach my $TOP (@TOP) {
+           local $@;
+           $rv++ if eval $code;
+           $RT::Logger->error("Cannot eval code: $@") if $@;
+       }
+
+       if ($rv or !@TOP) {
+           $obj->SetStatus( Status     => 'resolved', Force    => 1,);
+       }
+       else {
+           $obj->SetStatus( Status     => 'rejected', Force    => 1,);
+       }
+    }
+}
+
+# Now magically turn myself into a Requestor Notify object...
+require RT::Action::Notify; bless($self, 'RT::Action::Notify');
+$self->{Argument} = 'Requestor'; $self->Prepare;
+
+return 0; # ignore $passed;
+# ------------------------------------------------------------------- #
+       ],
+       CustomCommitCode => '"never needed"',
+       Template => 'All Approvals Passed', },
+
+);
+
+@ACL = (
+    { UserId => 'Nobody',      # - principalId
+      Right  => 'OwnTicket', },
+
+    { UserId => 'root',        # - principalid
+      Right  => 'SuperUser', },
+
+);
+
+# Predefined searches
+
+@Attributes = (
+    { Name => 'Search - My Tickets',
+      Description => '[_1] highest priority tickets I own', # loc
+      Content     =>
+      { Format => "'<a href=\"__WebPath__/Ticket/Display.html?id=__id__\">__id__</a>/TITLE:#', '<a href=\"__WebPath__/Ticket/Display.html?id=__id__\">__Subject__</a>/TITLE:Subject', Priority, QueueName, ExtendedStatus",
+        Query   => " Owner = '__CurrentUser__' AND ( Status = 'new' OR Status = 'open')",
+        OrderBy => 'Priority',
+        Order   => 'DESC' },
+    },
+    { Name => 'Search - Unowned Tickets',
+      Description => '[_1] newest unowned tickets', # loc
+      Content     =>
+# 'Take' #loc
+      { Format => "'<a href=\"__WebPath__/Ticket/Display.html?id=__id__\">__id__</a>/TITLE:#', '<a href=\"__WebPath__/Ticket/Display.html?id=__id__\">__Subject__</a>/TITLE:Subject', QueueName, ExtendedStatus, CreatedRelative, '<A HREF=\"__WebPath__/Ticket/Display.html?Action=Take&id=__id__\">__loc(Take)__</a>/TITLE:&nbsp;' ",
+        Query   => " Owner = 'Nobody' AND ( Status = 'new' OR Status = 'open')",
+        OrderBy => 'Created',
+        Order   => 'DESC' },
+    },
+    { Name => 'HomepageSettings',
+      Description => 'HomepageSettings',
+      Content =>
+      { 'body' => # loc
+       [ { type => 'system', name => 'My Tickets' },
+         { type => 'system', name => 'Unowned Tickets' },
+         { type => 'component',  name => 'QuickCreate'},
+       ],
+        'summary' => # loc
+       [ 
+         { type => 'component', name => 'MyReminders' },
+          { type => 'component', name => 'Quicksearch' },
+         { type => 'component', name => 'RefreshHomepage' },
+       ]
+    },
+}
+);
diff --git a/rt3/monitor-rt3.init b/rt3/monitor-rt3.init
new file mode 100644 (file)
index 0000000..abd770e
--- /dev/null
@@ -0,0 +1,189 @@
+#!/bin/bash
+#
+# priority: 850
+#
+# Manage settings for the Zabbix installtion and 
+#      other monitor-related things
+#
+# Stephen Soltesz <soltesz@cs.princeton.edu>
+# Copyright (C) 2008 The Trustees of Princeton University
+#
+# $Id$
+#
+
+# Source function library and configuration
+. /etc/plc.d/functions
+. /etc/planetlab/plc_config
+local_config=/etc/planetlab/configs/site.xml
+
+MONITORPATH=/usr/share/monitor
+
+# Be verbose
+set -x
+
+# Default locations
+PGDATA=/var/lib/pgsql/data
+postgresql_conf=$PGDATA/postgresql.conf
+pghba_conf=$PGDATA/pg_hba.conf
+
+# Export so that we do not have to specify -p to psql invocations
+export PGPORT=$PLC_DB_PORT
+
+
+RT3_DB_USER="rt3user"
+RT3_DB_NAME="rt3"
+
+WROTE_PG_CONFIG=
+
+if [ -z "$PLC_MONITOR_IP" ] ; then
+       PLC_MONITOR_IP=$( gethostbyname $PLC_MONITOR_HOST )
+fi
+
+if [ "$PLC_MONITOR_ENABLED" != "1" ] ; then
+    exit 0
+fi
+
+# TODO: make values re-configurable...  this may be an issue with RT's db, though.
+function update_config ()
+{
+       pattern=$1
+       with=$2
+       file=$3
+       sed -i -e "s/$pattern/$with/g" $file
+}
+
+function check_rt_siteconfig ()
+{
+       tmp_siteconfig=$(mktemp)
+       tmp_initialdata=$(mktemp)
+       
+       # if the templates are newer than the actual config, then replace them.
+       if [ $MONITORPATH/rt3/RT_SiteConfig.pm -nt /etc/rt3/RT_SiteConfig.pm ] ;
+       then
+               # copy templates
+               cp -f $MONITORPATH/rt3/RT_SiteConfig.pm $tmp_siteconfig
+               cp -f $MONITORPATH/rt3/initialdata $tmp_initialdata
+
+               # setup RT_SiteConfig.pm
+               update_config PLC_NAME $PLC_NAME $tmp_siteconfig
+               update_config PLC_RT_HOSTNAME $PLC_RT_HOSTNAME $tmp_siteconfig
+
+               update_config RT_DB_NAME $RT3_DB_NAME $tmp_siteconfig
+               update_config RT_DB_USER $RT3_DB_USER $tmp_siteconfig
+               update_config RT_DB_PASSWORD $PLC_MONITOR_DBPASSWORD $tmp_siteconfig
+
+               # setup initialdata
+               update_config PLC_RT_HOSTNAME $PLC_RT_HOSTNAME $tmp_initialdata
+
+               # copy to live configuration
+               cp -f $tmp_siteconfig /etc/rt3/RT_SiteConfig.pm 
+               cp -f $tmp_initialdata /etc/rt3/initialdata 
+
+               rm -f $tmp_siteconfig
+               rm -f $tmp_initialdata
+       fi
+}
+
+function check_rt_pghba ()
+{
+       NAME=$RT3_DB_NAME
+       USER=$RT3_DB_USER
+       CONF=$PGDATA/pg_hba.conf.d/${NAME}.conf
+       PATTERN="host all postgres 127.0.0.1/32 trust"
+
+       if ! grep -q $PATTERN $CONF ; then
+               #### SETUP ACCESS from postgres user to run init for the first time.
+               echo $PATTERN >> $CONF
+       fi
+
+}
+
+function check_rt_aliases ()
+{
+
+       if ! grep -q "rt-mailgate --queue support" /etc/aliases ; 
+       then 
+        cat <<EOF >> /etc/aliases
+
+# added by RT init scripts for default queues.
+support: "|/usr/sbin/rt-mailgate --queue support --action correspond --url http://localhost/rt3/"
+monitor: "|/usr/sbin/rt-mailgate --queue monitor --action correspond --url http://localhost/rt3/"
+security: "|/usr/sbin/rt-mailgate --queue security --action correspond --url http://localhost/rt3/"
+legal: "|/usr/sbin/rt-mailgate --queue legal --action correspond --url http://localhost/rt3/"
+EOF
+               /usr/bin/newaliases
+       fi
+
+}
+
+function check_rt_init ()
+{
+       if [ ! -f /etc/rt3/setup.finished ] ; then
+               /usr/sbin/rt-setup-database --action init --dba postgres
+               touch /etc/rt3/setup.finished
+       fi
+
+       ###Last DB adjustments
+       #disable queue General, set disabled to 0 in table queues, set defaultduein to 1 for support queue
+#      /bin/su - -c "/bin/echo \"UPDATE queues SET disabled = 1 WHERE name='General';\"|/usr/bin/psql -U postgres -d rt" postgres
+#      /bin/su - -c "/bin/echo \"UPDATE queues SET defaultduein = 1 WHERE name='support';\"|/usr/bin/psql -U postgres -d rt" postgres
+#
+       #alter acl for Everyone be able to create new tickets in support list
+       #Everyone (installation id 3) on support ( installation is 3)
+#      /bin/su - -c "/bin/echo \"INSERT INTO acl (principaltype,principalid,rightname,objecttype,objectid,delegatedby,delegatedfrom) VALUES ('Group',3,'CreateTicket','RT::Queue',3,0,0);\"|/usr/bin/psql -U postgres -d rt" postgres
+#      /bin/su - -c "/bin/echo \"INSERT INTO acl (principaltype,principalid,rightname,objecttype,objectid,delegatedby,delegatedfrom) VALUES ('Group',3,'ReplyToTicket','RT::Queue',3,0,0);\"|/usr/bin/psql -U postgres -d rt" postgres
+#      #Everyone (installation id 3) on monitor ( installation is 2)
+#      /bin/su - -c "/bin/echo \"INSERT INTO acl (principaltype,principalid,rightname,objecttype,objectid,delegatedby,delegatedfrom) VALUES ('Group',3,'CreateTicket','RT::Queue',2,0,0);\"|/usr/bin/psql -U postgres -d rt" postgres
+#      /bin/su - -c "/bin/echo \"INSERT INTO acl (principaltype,principalid,rightname,objecttype,objectid,delegatedby,delegatedfrom) VALUES ('Group',3,'ReplyToTicket','RT::Queue',2,0,0);\"|/usr/bin/psql -U postgres -d rt" postgres
+       
+}
+
+case "$1" in
+       start)
+               MESSAGE=$"Bootstrap RT (please wait...)"
+               dialog "$MESSAGE"
+
+               check_pg_hba $RT3_DB_NAME $RT3_DB_USER
+               check_user_and_db $RT3_DB_NAME $RT3_DB_USER
+               check_rt_siteconfig
+               check_rt_pghba
+               if [ -n "$WROTE_PG_CONFIG" ] ; then
+                       # NOTE: restart db to enable access by users granted above.
+                       service plc restart postgresql
+                       MESSAGE=$"Bootstrap RT 2 (please wait...)"
+                       dialog "$MESSAGE"
+               fi
+               check_rt_aliases
+               check_rt_init
+
+               result "$MESSAGE"
+       ;;
+
+
+       delete)
+               MESSAGE=$"Deleting databases..."
+               dialog "$MESSAGE"
+
+               dropdb -U postgres $RT3_DB_NAME
+               dropuser -U postgres $RT3_DB_USER
+               rm -f /etc/rt3/RT_SiteConfig.pm
+               rm -f /etc/rt3/initialdata
+               PATTERN="host all postgres 127.0.0.1/32 trust"
+               sed -i -e "s/$PATTERN//g" $PGDATA/pg_hba.conf.d/${RT3_DB_USER}.conf
+
+               sed -i -e "s/.*mailgate.*//g" /etc/aliases
+
+               result "$MESSAGE"
+       ;;
+
+       stop)
+               MESSAGE=$"Stopping Monitor"
+               dialog "$MESSAGE"
+
+               # TODO: is there anything to stop?
+
+               result "$MESSAGE"
+       ;;
+esac
+
+exit $ERRORS
diff --git a/web/MonitorWeb/monitorweb/templates/actionsummary.kid b/web/MonitorWeb/monitorweb/templates/actionsummary.kid
new file mode 100644 (file)
index 0000000..b6f4955
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<?python
+layout_params['page_title'] = "Monitor Node View"
+from monitor.util import diff_time
+from monitor import config
+from time import mktime
+from links import *
+
+def zabbix_event_ack_link(eventid):
+       return "http://" + config.MONITOR_HOSTNAME + "/zabbix/acknow.php?eventid=" + str(eventid)
+
+?>
+<html py:layout="'sitemenu.kid'"
+      xmlns:py="http://purl.org/kid/ns#"
+         xmlns:mochi="http://www.mochi.org">
+
+  <div py:match="item.tag == 'content'">
+       <table width="100%">
+               <thead>
+                       <tr>
+                               <th>Last Day</th>
+                               <th>Last Week</th>
+                               <th>Last Month</th>
+                       </tr>
+               </thead>
+               <tbody>
+               <tr>
+               <td colspan="5">
+               <table id="sortable_table" class="datagrid" border="1" width="100%">
+                       <thead>
+                               <tr>
+                                       <th mochi:format="int"></th>
+                                       <th>Notice Name</th>
+                                       <th>Count</th>
+                               </tr>
+                       </thead>
+                       <tbody>
+                               <tr py:for="key in results.keys()">
+                                       <td></td>
+                                       <td nowrap="true" py:content="key"></td>
+                                       <td nowrap='true' py:content="results[key]"></td>
+                               </tr>
+                       </tbody>
+               </table>
+               </td>
+               </tr>
+               </tbody>
+       </table>
+  </div>
+
+</html>
diff --git a/zabbix/monitor-zabbix.init b/zabbix/monitor-zabbix.init
new file mode 100644 (file)
index 0000000..185f767
--- /dev/null
@@ -0,0 +1,208 @@
+#!/bin/bash
+#
+# priority: 850
+#
+# Manage settings for the Zabbix installtion and 
+#      other monitor-related things
+#
+# Stephen Soltesz <soltesz@cs.princeton.edu>
+# Copyright (C) 2008 The Trustees of Princeton University
+#
+# $Id$
+#
+
+# Source function library and configuration
+. /etc/plc.d/functions
+. /etc/plc.d/monitor.functions
+. /etc/planetlab/plc_config
+local_config=/etc/planetlab/configs/site.xml
+
+MONITORPATH=/usr/share/monitor
+# Be verbose
+set -x
+
+
+function if_present_load ()
+{
+    file=$1
+    if [ -f $file ] ; then
+        psql -d $ZABBIX_DB_NAME -U $ZABBIX_DB_USER < $file
+    fi
+}
+
+
+function check_zabbix_schema_and_data() 
+{
+    schema_present=$( psql -U $ZABBIX_DB_USER $ZABBIX_DB_NAME -c "\d;" < /dev/null | grep hosts )
+    if [ -z $schema_present ] ; then
+        echo "... initial import can take SEVERAL minutes. please wait ..."
+        if_present_load "/usr/local/zabbix/misc/create/schema/postgresql.sql"
+        if_present_load "/usr/local/zabbix/misc/create/data/data.sql"
+        if_present_load "/usr/local/zabbix/misc/create/data/images_pgsql.sql"
+       ## TODO: update ZABBIX Server entry, "update hosts set status=0, host='MyPLC Server' where hostid=10017"
+    fi
+}
+
+function check_zabbix_templates_and_import ()
+{
+       # LOG IN
+       COOKIE_FILE=/tmp/cookiejar.txt
+       rm -f ${COOKIE_FILE}
+       TEMPLATES_DIR=${MONITORPATH}/zabbix/templates
+       curl -s --cookie $COOKIE_FILE --cookie-jar $COOKIE_FILE \
+                       --form "enter=Enter" \
+                       --form "name=Admin" \
+                       --form "password=zabbix" \
+                       "http://${PLC_MONITOR_HOST}/zabbix/index.php?login=1"
+       
+       deleted=$( grep 'deleted' $COOKIE_FILE )
+       if [ -n "$deleted" ] ; then
+               echo "Login to the zabbix web server failed!!!"
+               return 1
+       fi
+
+       for file in ${TEMPLATES_DIR}/*.xml ; do 
+               # 0 - update , 1 - skip, 0 - add
+               echo "############### IMPORTING $file" >> /var/log/monitor.log
+               curl -s --cookie $COOKIE_FILE --cookie-jar $COOKIE_FILE \
+                       --form "config=1" \
+                       --form "import_file=@${file}" \
+                       --form "rules[host][exist]=0" \
+                       --form "rules[host][missed]=0" \
+                       --form "rules[template][exist]=0" \
+                       --form "rules[template][missed]=1" \
+                       --form "rules[item][exist]=0" \
+                       --form "rules[item][missed]=0" \
+                       --form "rules[trigger][exist]=0" \
+                       --form "rules[trigger][missed]=0" \
+                       --form "rules[graph][exist]=0" \
+                       --form "rules[graph][missed]=0" \
+                       --form "import=Import" \
+                       "http://${PLC_MONITOR_HOST}/zabbix/exp_imp.php" >> /var/log/monitor.log
+       done
+}
+
+function check_zab_server ()
+{
+       ZABBIXCFG=/etc/zabbix
+       TMP_FILE=`mktemp /tmp/zbxtmpXXXXXX`
+
+       if [ -f ${ZABBIXCFG}/zabbix_server.conf ] ; then
+               sed -e "s/#DBHost=.*/DBHost=$PLC_MONITOR_HOST/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" \
+                   ${ZABBIXCFG}/zabbix_server.conf > $TMP_FILE
+               cat $TMP_FILE > ${ZABBIXCFG}/zabbix_server.conf
+       fi
+       service zabbix_server start
+       rm -f $TMP_FILE
+
+}
+function check_zab_agentd ()
+{
+       ZABBIXCFG=/etc/zabbix
+       TMP_FILE=`mktemp /tmp/zbxtmpXXXXXX`
+       if [ -f ${ZABBIXCFG}/zabbix_agentd.conf ] ; then
+               HOST=`hostname`
+               sed -e "s#Server=.*#Server=$PLC_MONITOR_HOST#g" \
+                   -e "s#Hostname=.*#Hostname=$HOST#g" \
+                   ${ZABBIXCFG}/zabbix_agentd.conf > $TMP_FILE
+               cat $TMP_FILE > ${ZABBIXCFG}/zabbix_agentd.conf 
+       fi
+       service zabbix_agentd start
+       rm -f $TMP_FILE
+}
+function check_zab_webconfig()
+{
+       # SETUP zabbix gui configuration
+       ZABBIX_WEB_CFG=/var/www/html/zabbix/conf/zabbix.conf.php 
+       if [ ! -f $ZABBIX_WEB_CFG ] ; then
+               touch  $ZABBIX_WEB_CFG
+               cat <<EOF > $ZABBIX_WEB_CFG
+<?php
+global \$DB;
+
+\$DB["TYPE"]           = "POSTGRESQL";
+\$DB["SERVER"]         = "localhost";
+\$DB["PORT"]           = "0";
+\$DB["DATABASE"]               = "$ZABBIX_DB_NAME";
+\$DB["USER"]           = "$ZABBIX_DB_USER";
+\$DB["PASSWORD"]               = "$PLC_MONITOR_DBPASSWORD";
+\$ZBX_SERVER           = "$PLC_MONITOR_HOST";
+\$ZBX_SERVER_PORT      = "10051";
+\$IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG;
+?>
+EOF
+               chmod 644 $ZABBIX_WEB_CFG
+       fi
+}
+
+case "$1" in
+       start)
+               MESSAGE=$"Bootstrap Zabbix (please wait...)"
+               dialog "$MESSAGE"
+
+               # DATABASE acces, creation, and data loading
+               check_pg_hba $ZABBIX_DB_NAME $ZABBIX_DB_USER
+               check_user_and_db $ZABBIX_DB_NAME $ZABBIX_DB_USER
+
+               if [ -n "$WROTE_PG_CONFIG" ] ; then
+                       # NOTE: restart db to enable access by users granted above.
+                       service plc restart postgresql
+                       service plc restart httpd
+                       MESSAGE=$"Bootstrap Zabbix 2 (please wait...)"
+                       dialog "$MESSAGE"
+               fi
+
+               check_zabbix_schema_and_data
+               check_zabbix_templates_and_import
+
+               # START zabbix services.  SETUP default config files.
+               check_zab_server
+               check_zab_agentd
+               check_zab_webconfig
+
+               result "$MESSAGE"
+       ;;
+
+       sync)
+               MESSAGE=$"Syncing PLC db with Zabbix DB"
+               dialog "$MESSAGE"
+
+               # turn off zabbix server, etc. before writing to the db.
+               service plc stop monitor-zabbix
+
+               $MONITORPATH/zabbix/zabbixsync.py --setupids &> /var/log/monitor-server
+               $MONITORPATH/zabbix/zabbixsync.py --setupglobal 2>&1 >> /var/log/monitor-server
+               # import any templates
+               check_zabbix_templates_and_import
+
+               service plc start monitor-zabbix 
+               
+               result "$MESSAGE"
+       ;;
+
+       delete)
+               MESSAGE=$"Deleting Zabbix databases..."
+               dialog "$MESSAGE"
+
+               dropdb -U postgres $ZABBIX_DB_NAME
+               dropuser -U postgres $ZABBIX_DB_USER
+
+               result "$MESSAGE"
+       ;;
+
+       stop)
+               MESSAGE=$"Stopping Zabbix"
+               dialog "$MESSAGE"
+
+               service zabbix_server stop
+               service zabbix_agentd stop
+
+               result "$MESSAGE"
+       ;;
+esac
+
+exit $ERRORS