Page MenuHomeGRNET

No OneTemporary

File Metadata

Created
Fri, Aug 29, 1:58 PM
diff --git a/ici b/ici
new file mode 100755
index 0000000..d51fcaa
--- /dev/null
+++ b/ici
@@ -0,0 +1,233 @@
+#!/usr/bin/env python
+from operator import itemgetter
+import json, socket, urllib2
+import sys, os, time
+import argparse
+
+# hardcoded for now
+monitoring_url = "194.177.210.168:1337"
+
+
+# Hack to set a default subcommand (needed for status).
+#
+def set_default_subparser(self, name, args=None):
+ """default subparser selection. Call after setup, just before parse_args()
+ name: is the name of the subparser to call by default
+ args: if set is the argument list handed to parse_args()
+ , tested with 2.7, 3.2, 3.3, 3.4
+ it works with 2.6 assuming argparse is installed
+ """
+ subparser_found = False
+ for arg in sys.argv[1:]:
+ if arg in ['-h', '--help']: # global help if no subparser
+ break
+ else:
+ for x in self._subparsers._actions:
+ if not isinstance(x, argparse._SubParsersAction):
+ continue
+ for sp_name in x._name_parser_map.keys():
+ if sp_name in sys.argv[1:]:
+ subparser_found = True
+ if not subparser_found:
+ # insert default in first position, this implies no
+ # global options without a sub_parsers specified
+ if args is None:
+ sys.argv.insert(1, name)
+ else:
+ args.insert(0, name)
+
+argparse.ArgumentParser.set_default_subparser = set_default_subparser
+
+def host_status(hostname,status_all):
+ # need to escape the \n in the URL
+ api_query = "http://" + monitoring_url + \
+ "/query?q=GET%20hosts\\nFilter:%20alias%20=%20" + hostname
+ # handle livestatus-service being down
+ try:
+ req = urllib2.urlopen(api_query).read()
+ except URLError:
+ sys.exit("Could not contact livestatus-service.")
+ # handle getting garbage reply
+ try:
+ full = json.loads(req)
+ except ValueError:
+ sys.exit("Invalid livestatus request.")
+ # handle host not having parents registered in icinga
+ try:
+ parent_list = "[Parents: " + " ".join(set(full[0].get('parents'))) + "]"
+ except IndexError:
+ parent_list = ""
+
+ print "Host: \033[92m" + full[0].get('display_name') + "\033[0m " + parent_list
+ print "Hostgroups: " + " ".join(full[0].get("groups"))
+
+ # Flexible downtime could get messy here, because the could be an
+ # item in this list but no an active downtime on the host
+ if full[0].get('downtimes_with_info'):
+ print "\033[1;36mHost is in downtime: " + \
+ full[0].get('downtimes_with_info')[0][2] + \
+ "(" + full[0].get('downtimes_with_info')[0][1] + ")\033[0m"
+
+ # This could also get tricky, i'm assuming the first comment is
+ # the one generated by icinga from the downtime command
+ print "\033[1;36m" + full[0].get('comments_with_info')[0][2].split(". ")[0] + "\033[0m"
+
+ # Display full checks list (colors W/C/U)
+ status = full[0].get('services_with_fullstate')
+ print "Status: " + str(full[0].get('num_services_hard_warn')) + " warn, " + \
+ str(full[0].get('num_services_hard_crit')) + " crit, " + \
+ str(full[0].get('num_services_hard_unknown')) + \
+ " unknown, " + str(full[0].get('num_services')) + " total."
+
+ for i in sorted(status, key=itemgetter(0)):
+ if i[1] == 0: #OK
+ if status_all:
+ print ' - \033[92m%s\033[0m- \033[0;32m%s \033[0m' % (i[0], i[3])
+ else:
+ pass
+ elif i[1] == 1:
+ print '\033\t[93m%s- %s \033[0m' % (i[0], i[3])
+ elif i[1] == 2:
+ print '\033\t[91m%s- %s \033[0m' % (i[0], i[3])
+ elif i[1] == 3:
+ print '\033\t[94m%s- %s \033[0m' % (i[0], i[3])
+
+def downtime(hostname, duration, service, dt_type):
+ cur_time = int( time.time() )
+ dest_time = cur_time + int(duration)
+ user=os.environ['USER']
+
+ # livestatus-service doesn't need the first time in brackets
+ if dt_type == 0:
+ ici_cmd = "SCHEDULE_SVC_DOWNTIME;" + hostname + ";" + service + ";" + str(cur_time) + ";" + \
+ str(dest_time) + ";" + str(dt_type) + ";0;" + str(duration) + \
+ ";" + user + ";downtime_by_script"
+ elif dt_type == 1:
+ ici_cmd = "SCHEDULE_HOST_SVC_DOWNTIME;" + hostname + ";" + str(cur_time) + ";" + \
+ str(dest_time) + ";" + str(dt_type) + ";0;" + str(duration) + ";" + user + \
+ ";downtime_by_script"
+ else:
+ ici_cmd = "SCHEDULE_SERVICEGROUP_SVC_DOWNTIME;" + service + ";" + str(cur_time) + ";" + \
+ str(dest_time) + ";1;0;" + str(duration) + ";" + user + ";downtime_by_script"
+
+ cmd_query = "http://" + monitoring_url + "/cmd?q=" + ici_cmd
+ req = urllib2.urlopen(cmd_query).read()
+ print req.rstrip("\n")
+
+def ack(hostname, service, notify, comment):
+ cur_time = int( time.time() )
+ user=os.environ['USER']
+ ici_cmd = "ACKNOWLEDGE_SVC_PROBLEM;" + hostname + ";" + service + \
+ ";2;1;" + str(notify) + ";" + user + ";ACK%20By%20Script%20" + \
+ comment.replace(" ","%20")
+ cmd_query = "http://" + monitoring_url + "/cmd?q=" + ici_cmd
+ req = urllib2.urlopen(cmd_query).read()
+ print req.rstrip("\n")
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+
+ # top-level parser.
+ parser = argparse.ArgumentParser(prog='ici')
+ subparsers = parser.add_subparsers(help='')
+
+ # parser for status subcommand.
+ parser_a = subparsers.add_parser(
+ 'status',
+ help='Returns the status of a host'
+ )
+ parser_a.set_defaults(function=host_status)
+ parser_a.add_argument(
+ "hostname",
+ help="The fqdn of the host to see it's status",
+ default=socket.getfqdn().strip(),
+ nargs='?'
+ )
+ parser_a.add_argument(
+ "-a","--all",
+ help="Show the status of OK services too",
+ action="store_true"
+ )
+
+ # parser for downtime subcommand.
+ parser_b = subparsers.add_parser(
+ 'downtime',
+ help='schedules downtime for a host or a group of services'
+ )
+ parser_b.set_defaults(function=downtime)
+
+ # if a service group is defined then no hostname is needed.
+ group = parser_b.add_mutually_exclusive_group()
+ group.add_argument(
+ "hostname",
+ help="The fqdn of the host you want to schedule downtime",
+ default=socket.getfqdn().strip(),
+ nargs='?'
+ )
+ group.add_argument(
+ "-g", "--service-group",
+ help="The group of service to be scheduled for downtime",
+ nargs=1
+ )
+ parser_b.add_argument(
+ "-t", "--downtime",
+ help = "Downtime in seconds",
+ nargs='?',
+ default=3600,
+ type=int
+ )
+ parser_b.add_argument(
+ "-s", "--service",
+ help="Service Name",
+ nargs=1
+ )
+
+ # parser for ack subcommand.
+ parser_c = subparsers.add_parser(
+ 'ack',
+ help='Acknowledge a problem'
+ )
+ parser_c.set_defaults(function=ack)
+ parser_c.add_argument(
+ "hostname",
+ help="The fqdn of the host of the problem to acknowledge",
+ default=socket.getfqdn().strip(),
+ nargs='?'
+ )
+ parser_c.add_argument(
+ "-s", "--service",
+ help="Service Name",
+ nargs=1
+ )
+ parser_c.add_argument(
+ "-n", "--notify",
+ help="Notify",
+ action='store_true'
+ )
+ parser_c.add_argument(
+ "-c", "--comment",
+ help="Comment to accompany the ack",
+ nargs=1
+ )
+
+ parser.set_default_subparser('status')
+ args = parser.parse_args()
+
+ if args.function == host_status:
+ host_status(args.hostname, args.all)
+ elif args.function == downtime:
+ if args.service_group and args.service:
+ parser.error("You can either specify a hostname and a service to \
+ downtime or a group of services.\n -s and -g are mutually exclusive.")
+ elif args.service:
+ downtime(args.hostname, args.downtime, args.service[0], 0)
+ elif args.service_group:
+ downtime("", args.downtime, args.service_group[0], 2)
+ else:
+ downtime(args.hostname, args.downtime, "", 1)
+ elif args.function == ack:
+ if args.notify is False:
+ notify = 0
+ else:
+ notify = 1
+ ack(args.hostname, args.service[0], notify, args.comment[0])

Event Timeline