export PGPORT=$PLC_DB_PORT
-ZABBIX_DB_USER="zabbixuser"
-ZABBIX_DB_NAME="zabbix"
-
MONITOR_DB_USER="monitoruser"
MONITOR_DB_NAME="monitor"
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}'})
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
# 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
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
fi
start_tg_server
- # START zabbix services. SETUP default config files.
- #check_zab_server
- #check_zab_agentd
- #check_zab_webconfig
-
result "$MESSAGE"
;;
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
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
--- /dev/null
+# 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: ' ",
+ 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' },
+ ]
+ },
+}
+);
--- /dev/null
+#!/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
--- /dev/null
+#!/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