Page Menu
Home
GRNET
Search
Configure Global Search
Log In
Files
F904781
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, Aug 29, 1:58 PM
Size
8 KB
Mime Type
text/x-diff
Expires
Sun, Aug 31, 1:58 PM (1 d, 14 h)
Engine
blob
Format
Raw Data
Handle
252239
Attached To
rICI livestatus-ici
View Options
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
Log In to Comment