ソースを参照

Nagios status module added

master
Dirk Alders 3ヶ月前
コミット
fd556d92ad
1個のファイルの変更200行の追加0行の削除
  1. 200
    0
      status.py

+ 200
- 0
status.py ファイルの表示

@@ -0,0 +1,200 @@
1
+import argparse
2
+import json
3
+import os
4
+import requests
5
+import time
6
+
7
+DEBUG = False
8
+
9
+
10
+class colors:
11
+    HEADER = '\033[95m'
12
+    OKBLUE = '\033[94m'
13
+    OKCYAN = '\033[96m'
14
+    OKGREEN = '\033[92m'
15
+    WARNING = '\033[93m'
16
+    FAIL = '\033[91m'
17
+    ENDC = '\033[0m'
18
+    BOLD = '\033[1m'
19
+    UNDERLINE = '\033[4m'
20
+
21
+
22
+def headline(color: bool) -> str:
23
+    rv = ""
24
+    if color:
25
+        rv += colors.BOLD + colors.UNDERLINE
26
+    rv += "NAGIOS Status:"
27
+    if color:
28
+        rv += colors.ENDC
29
+    rv += "\n\n"
30
+    return rv
31
+
32
+
33
+class nagios_service(dict):
34
+    SID_OK = 2
35
+    SID_WARNING = 4
36
+    SID_ERROR = 16
37
+    #
38
+    SNAME_OK = "OKAY"
39
+    SNAME_FLAPPING = "FLAPPING"
40
+    SNAME_WARNING = "WARNING"
41
+    SNAME_ERROR = "ERROR"
42
+    SNAME_UNKNOWN = "UNKNOWN"
43
+    TIMEFORMAT = "%d.%m.%Y %H:%M"
44
+
45
+    def __init__(self, service_dict) -> None:
46
+        super().__init__(service_dict)
47
+
48
+    def is_problem(self):
49
+        return self["status"] != self.SID_OK or self.flapping()
50
+
51
+    def host_name(self):
52
+        return self['host_name']
53
+
54
+    def name(self):
55
+        return self['description']
56
+
57
+    def status(self):
58
+        status = self["status"]
59
+        default = self.SNAME_UNKNOWN
60
+        if status == self.SID_OK and self.flapping():
61
+            return self.SNAME_FLAPPING
62
+        return {
63
+            self.SID_OK: self.SNAME_OK,
64
+            self.SID_WARNING: self.SNAME_WARNING,
65
+            self.SID_ERROR: self.SNAME_ERROR
66
+        }.get(status, default)
67
+
68
+    def last_okay(self):
69
+        return time.strftime(self.TIMEFORMAT, time.localtime(self["last_time_ok"] / 1000))
70
+
71
+    def info(self):
72
+        return self.get("plugin_output") or self.get("long_plugin_output")
73
+
74
+    def flapping(self):
75
+        return self["is_flapping"]
76
+
77
+    def __color__(self):
78
+        return {
79
+            self.SNAME_OK: colors.OKGREEN,
80
+            self.SNAME_FLAPPING: colors.OKBLUE,
81
+            self.SNAME_WARNING: colors.WARNING,
82
+            self.SNAME_ERROR: colors.FAIL,
83
+            self.SNAME_UNKNOWN: colors.OKCYAN
84
+        }.get(self.status())
85
+
86
+        return colors.OKBLUE
87
+
88
+    def __head__(self, color=False):
89
+        rv = headline(color)
90
+        rv += "+-----------------------------------------------------------------------------------------\n"
91
+        rv += "| Host                      | Service Name    | State    | Last time Okay   |\n"
92
+        rv += "+---------------------------+-----------------+----------+------------------+-------------\n"
93
+        return rv
94
+
95
+    def __foot__(self):
96
+        return "+---------------------------+-----------------+----------+------------------+-------------\n"
97
+
98
+    def __str__(self, color=False):
99
+        cols = []
100
+        cols.append((self.host_name, 25, False))
101
+        cols.append((self.name, 15, color))
102
+        cols.append((self.status, 8, color))
103
+        cols.append((self.last_okay, 16, color))
104
+        cols.append((self.info, 0, False))
105
+        #
106
+        rv = ""
107
+        for txt_method, l, c in cols:
108
+            txt = txt_method()
109
+            if len(rv) > 0:
110
+                rv += " | "
111
+            if c:
112
+                if txt_method == self.last_okay:
113
+                    rv += colors.OKGREEN
114
+                else:
115
+                    rv += self.__color__()
116
+            if l > 0:
117
+                rv += txt[:l]
118
+                rv += " " * (l-len(txt))
119
+            else:
120
+                rv += txt
121
+            if c:
122
+                rv += colors.ENDC
123
+        #
124
+        rv = "| " + rv + "\n"
125
+        if DEBUG:
126
+            rv += json.dumps(self, indent=4, sort_keys=True)
127
+        return rv
128
+
129
+
130
+class __nagios_status__(dict):
131
+    def __init__(self) -> None:
132
+        super().__init__()
133
+
134
+    def all_problems(self):
135
+        rv = __nagios_status__()
136
+        for host in self:
137
+            for service in self[host]:
138
+                if service.is_problem():
139
+                    rv.__add_service__(host, service)
140
+        return rv
141
+
142
+    def __add_service__(self, host, service):
143
+        if host not in self:
144
+            self[host] = []
145
+        self[host].append(nagios_service(service))
146
+
147
+    def __str__(self, color=False) -> str:
148
+        rv = ""
149
+        for host in self:
150
+            for service in self[host]:
151
+                if len(rv) == 0:
152
+                    rv += service.__head__(color=color)
153
+                rv += service.__str__(color=color)
154
+        if len(rv) > 0:
155
+            rv += service.__foot__()
156
+        else:
157
+            rv += headline(color)
158
+            rv += "No monitorings to be reported."
159
+        return rv + "\n"
160
+
161
+
162
+class nagios_status(__nagios_status__):
163
+    URL = "nagios4/cgi-bin/statusjson.cgi?query=servicelist&details=true"  # &servicestatus=warning"
164
+    KEY_DATA = 'data'
165
+    KEY_SERVICELIST = 'servicelist'
166
+
167
+    def __init__(self, host, secure) -> None:
168
+        super().__init__()
169
+        #
170
+        if secure:
171
+            prefix = "https://"
172
+        else:
173
+            prefix = "http://"
174
+        r = requests.get(os.path.join(prefix, host, self.URL))
175
+        data = r.json()
176
+
177
+        hosts = data.get(self.KEY_DATA, {}).get(self.KEY_SERVICELIST, {})
178
+        for host in hosts:
179
+            for service in hosts.get(host, {}):
180
+                self.__add_service__(host, hosts.get(host).get(service))
181
+
182
+
183
+if __name__ == "__main__":
184
+    parser = argparse.ArgumentParser(description="Returns the status of all or partial nagios monitorings.")
185
+    parser.add_argument("hostname", help="The hostname and port of the nagios server (e.g. nagios:8080)")
186
+    parser.add_argument("-a", "--all", action="store_true", default=False,
187
+                        help="print the status of all nagios monitorings. Default is all problems.")
188
+    parser.add_argument("-s", "--secure", action="store_true", default=False, help="Enables secure connection (https)")
189
+    parser.add_argument("-m", "--monochrome", action="store_true", default=False, help="No colored output")
190
+    args = parser.parse_args()
191
+    #
192
+    try:
193
+        s = nagios_status(args.hostname, args.secure)
194
+    except requests.ConnectionError:
195
+        print(headline(not args.monochrome) + "Can not connect to given host.")
196
+    else:
197
+        if args.all:
198
+            print(s.__str__(color=not args.monochrome))
199
+        else:
200
+            print(s.all_problems().__str__(color=not args.monochrome))

読み込み中…
キャンセル
保存