xmppnotify.py 5.73 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# pip3 install dnspython

import argparse
import configparser
from slixmpp import ClientXMPP
from socket import gethostname

class XMPPNotify(ClientXMPP):
Bernhard Geier's avatar
Bernhard Geier committed
11
    def __init__(self, jid, password, nick, recipient, msg):
12
13
14
        ClientXMPP.__init__(self, jid, password)
        self.recipient = recipient
        self.msg = msg
Bernhard Geier's avatar
Bernhard Geier committed
15
        self.nick = nick
16
17
18
        self.add_event_handler("session_start", self.session_start)
        # self.add_event_handler("message", self.message)

Bernhard Geier's avatar
Bernhard Geier committed
19
20

    async def session_start(self, event):
21
        self.send_presence()
Bernhard Geier's avatar
Bernhard Geier committed
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
        await self.get_roster()

        recipient_type = "account"
        try:
            info = await self['xep_0030'].get_info(jid=self.recipient)
            disco_info=info['disco_info']
            if disco_info:
                for category, typ, _, name in disco_info['identities']:
                    if category == "conference":
                        recipient_type = "muc"
                        break
        except:
            # Some servers do not support Service Discovery (XEP-0030)
            # Assume they don't support MUCs (XEP-0045) as well
            pass

        if recipient_type == "muc":
            self.plugin['xep_0045'].join_muc(self.recipient, self.nick)
            self.send_message(mto=self.recipient, mbody=self.msg, mtype='groupchat')
        else:
            self.send_message(mto=self.recipient, mbody=self.msg, mtype='chat')

44
45
46
47
48
49
50
        self.disconnect()

    def message(self, msg):
        pass


def build_message(args):
51
52
53
54
55
56
    # Prefix all output lines by "> "
    if args.output:
        output = "> " + args.output.replace("\n", "\n> ")
    else:
        output = ""

57
58
    if args.servicename:
        # service
59
        message = """[{notificationtype}] {servicedisplayname} on {hostdisplayname} is {servicestate}!\n{output}""".format(
60
            notificationtype=args.notificationtype,
61
62
63
            servicedisplayname=args.servicedisplayname,
            hostdisplayname=args.hostdisplayname,
            servicestate=args.state,
64
65
            output=output

66
        )
67
68
69
70
71
72
73
        if not args.brief:
            message += """\nWhen: {longdatetime}\nRef: {hostname}!{servicename}\nMonitoring host: {monitoringhostname}""".format(
                longdatetime=args.longdatetime,
                hostname=args.hostname,
                servicename=args.servicename,
                monitoringhostname=gethostname()
            )
74
    else:
75
        message = """[{notificationtype}] {hostdisplayname} is {hoststate}!\n{output}""".format(
76
            notificationtype=args.notificationtype,
77
78
            hostdisplayname=args.hostdisplayname,
            hoststate=args.state,
79
80
81
82
            output=output
        )
        if not args.brief:
            message += """\nWhen: {longdatetime}\nRef: {hostname}\nMonitoring host: {monitoringhostname}""".format(
83
            longdatetime=args.longdatetime,
84
85
            hostname=args.hostname,
            monitoringhostname=gethostname()
86
87
        )

88
    if not args.brief and args.hostaddress:
Christian Tacke's avatar
Christian Tacke committed
89
        message += "\nIPv4: {}".format(args.hostaddress)
90

91
    if not args.brief and args.hostaddress6:
Christian Tacke's avatar
Christian Tacke committed
92
        message += "\nIPv6: {}".format(args.hostaddress6)
93
94

    if args.notificationcomment:
95
96
        # Prefix comment lines by "> "
        comment = "> " + args.notificationcomment.replace("\n", "\n> ")
Christian Tacke's avatar
Christian Tacke committed
97
98
        message += """\n
Comment by {notificationauthorname}
99
{comment}
100
101
""".format(
            notificationauthorname=args.notificationauthorname,
102
            comment=comment
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
        )

    if args.icingaweb2url and args.servicename:
        message += "\n" + args.icingaweb2url + \
            "/monitoring/service/show?host={hostname}&service={servicename}" \
            .format(
                hostname=args.hostname,
                servicename=args.servicename
            )
    elif args.icingaweb2url:
        message += "\n" + args.icingaweb2url + \
            "/monitoring/host/show?host={hostname}" \
            .format(
                hostname=args.hostname,
            )

    return message


122
def build_argparser():
123
    parser = argparse.ArgumentParser(description='XMPP Notifications')
124

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
    # required
    parser.add_argument('-d', '--longdatetime')
    parser.add_argument('-e', '--servicename')  # service only
    parser.add_argument('-l', '--hostname')
    parser.add_argument('-n', '--hostdisplayname')
    parser.add_argument('-o', '--output')  # host or service output
    parser.add_argument('-r', '--jid')
    parser.add_argument('-s', '--state')  # host or service state
    parser.add_argument('-u', '--servicedisplayname')  # service only
    parser.add_argument('-t', '--notificationtype')

    # optional
    parser.add_argument('-4', '--hostaddress')
    parser.add_argument('-6', '--hostaddress6')
    parser.add_argument('-b', '--notificationauthorname')
    parser.add_argument('-c', '--notificationcomment')
    parser.add_argument('-i', '--icingaweb2url')
142
    parser.add_argument('-B', '--brief', default=False, action='store_true')
143

144
145
146
147
148
149
150
151
    return parser


if __name__ == '__main__':
    config = configparser.RawConfigParser()
    config.read('/etc/xmppnotify.cfg')
    jid = config.get('Account', 'jid')
    password = config.get('Account', 'password')
Bernhard Geier's avatar
Bernhard Geier committed
152
    nick = config.get('Account', 'nick', fallback = jid.split("@")[0])
153
154

    parser = build_argparser()
155
156
157
    args = parser.parse_args()
    message = build_message(args)

Bernhard Geier's avatar
Bernhard Geier committed
158
    xmpp = XMPPNotify(jid, password, nick, args.jid, message)
159
160
    xmpp.register_plugin('xep_0030')  # Service Discovery
    xmpp.register_plugin('xep_0004')  # Data Forms
Bernhard Geier's avatar
Bernhard Geier committed
161
    xmpp.register_plugin('xep_0045')  # MUC
162
163
164
165
166
167
    xmpp.register_plugin('xep_0060')  # PubSub
    xmpp.register_plugin('xep_0199')  # XMPP Ping

    # Connect to the XMPP server and start processing XMPP stanzas.
    xmpp.connect()
    xmpp.process(forever=False)