#!/usr/bin/python
#
# Python script to send incidents from Zabbix to PagerDuty.
#
# Copyright (c) 2013-2014, PagerDuty, Inc. <info@pagerduty.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#   * Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#   * Neither the name of the copyright holder nor the
#     names of its contributors may be used to endorse or promote products
#     derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#

# Parse the Zabbix message body. The body MUST be in this format:
#
# name:{TRIGGER.NAME}
# id:{TRIGGER.ID}
# status:{TRIGGER.STATUS}
# hostname:{HOSTNAME}
# ip:{IPADDRESS}
# value:{TRIGGER.VALUE}
# event_id:{EVENT.ID}
# severity:{TRIGGER.SEVERITY}
#
def _parse_zabbix_body(body_str):
    return dict(line.strip().split(':', 1) for line in body_str.strip().split('\n'))

# Parse the Zabbix message subject.
# The subject MUST be one of the following:
#
# trigger
# resolve
#
def _parse_zabbix_subject(subject_str):
    return subject_str

def main():
    import sys
    from pdagent.pdagentutil import queue_event
    from pdagent.config import load_agent_config

    # The first argument is the service key
    service_key = sys.argv[1]

    # The second argument is the message type
    message_type = _parse_zabbix_subject(sys.argv[2])

    # The third argument is the data
    details = _parse_zabbix_body(sys.argv[3])

    # Zabbix issues a "trigger" with a "NOTE: Escalation cancelled" in details if the host,
    # trigger, or action gets disabled.
    # https://www.zabbix.com/documentation/3.2/manual/config/notifications/action/escalations
    # Convert that into a "resolve" to actually resolve the issue in PagerDuty
    if message_type == "trigger" and "NOTE" in details and "Escalation cancelled" in details["NOTE"]:
        message_type = "resolve"
        details["NOTE"] = details["NOTE"] + " (converted from trigger to resolve by pdagent integration)"

    # Incident key is created by concatenating trigger id and host name.
    # Remember, incident key is used for de-duping and also to match trigger with resolve messages
    incident_key = "%s-%s" % (details["id"], details["hostname"])

    # The description that is rendered in PagerDuty and also sent as SMS and phone alert
    description = "%s : %s for %s" % (details["name"], details["status"], details["hostname"])

    agent_config = load_agent_config()
    queue_event(
        agent_config.get_enqueuer(),
        message_type, service_key, incident_key, description, "", "", details,
        agent_config.get_agent_id(), "pd-zabbix",)

if __name__ == "__main__":
    try:
        import pdagent.config
    except ImportError:
        # Fix up for dev layout
        import sys
        from os.path import realpath, dirname
        sys.path.append(dirname(dirname(realpath(__file__))))
        import pdagent.config
    main()
