-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Defined UTF-8 encoding in all files; now the report type in wc_getRep…
…ort can be given as argument; added the new tool wc_checkAlarms
- Loading branch information
Showing
8 changed files
with
248 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# -*- coding: UTF-8 -*- | ||
|
||
|
||
class alarm: | ||
|
||
def __init__(self, date, age, standort, message, quelle, bestaetigtVon, kategorie, status): | ||
self.date = date | ||
#self.time = time | ||
self.age = age | ||
self.standort = standort | ||
self.message = message | ||
self.quelle = quelle | ||
self.bestaetigtVon = bestaetigtVon | ||
self.kategorie = kategorie | ||
self.status = status |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import suds | ||
import sys | ||
import xml | ||
import argparse | ||
import getpass | ||
from alarm import alarm | ||
from time import sleep | ||
import datetime | ||
|
||
|
||
def main(args): | ||
# Check all arguments | ||
try: | ||
if args['username'] is None: | ||
print 'No username specified. Login to WebCTRL needs a username and a password. Check all options for this command via -h' | ||
sys.exit(1) | ||
else: | ||
username = args['username'] | ||
except KeyError: | ||
print 'No "username" key specified. Please provide the key-value pair: \'username\':\'myUsername\'' | ||
sys.exit(1) | ||
|
||
try: | ||
if args['password'] is None: | ||
print 'No password specified. Login to WebCTRL needs a username and a password. Check all options for this command via -h' | ||
sys.exit(1) | ||
else: | ||
password = args['password'] | ||
except KeyError: | ||
print 'No "password" key specified. Please provide the key-value pair: \'password\':\'myPassword\'' | ||
sys.exit(1) | ||
|
||
try: | ||
if args['node'] is None: | ||
print 'No path to a node specified. Check all options for this command via -h' | ||
sys.exit(1) | ||
except KeyError: | ||
print 'No "node" key specified. Please provide the key-value pair: \'node\':\'/my/node\'' | ||
sys.exit(1) | ||
|
||
try: | ||
if args['url'] is None: | ||
print 'No URL given. Specify the URL to the WebCTRL server analogous to http://google.de' | ||
sys.exit(1) | ||
else: | ||
wsdlFile = args['url'] + '/_common/webservices/Report?wsdl' | ||
except KeyError: | ||
print 'No "url" key specified. Please provide the key-value pair: \'url\':\'http://myURL.de\'' | ||
sys.exit(1) | ||
|
||
|
||
# Connect to the webCTRL server | ||
try: | ||
client = suds.client.Client(wsdlFile, username=username, password=password) | ||
except AttributeError: | ||
print 'Error: Incorrect username and/or password' | ||
except xml.sax._exceptions.SAXParseException: | ||
print 'Error: Incorrect/Misspelled WSDL file. It should be: http(s)://URL?wsdl' | ||
sys.exit(1) | ||
except: | ||
print("Unexpected error:", sys.exc_info()[0]) | ||
print('Perhaps your URL to the WSDL file is not correct.') | ||
sys.exit(1) | ||
|
||
checkForNewAlarmsInterval = args['interval'] | ||
alarmsRunning = [] # running alarms waiting to be checked/acknowledged and, eventually, switched off | ||
alarmsChecked = [] # alarms that are already acknowloedged or switched off | ||
|
||
# As long as this script runs get a report about all current alarms and their status every X seconds. The alarms are | ||
# managed in objects that will be deleted once the status of an alarm has switched to "Normal". It will be checked | ||
# if an alarm is handled - at least acknowledged - in a certain amount of time and, if not, consequences follow as | ||
# e.g. e-mail or SMS to a given address or telephone number. | ||
while True: | ||
# Get a report about all current alarms in the network or in parts of the network (depending on the node setting) | ||
try: | ||
report = client.service.runReport(args['node'], '~alarms', 'csv') | ||
except suds.WebFault as fault: | ||
print fault | ||
sys.exit(1) | ||
|
||
print report | ||
|
||
lines = report.split("\n") | ||
lines = lines[1:] | ||
#file = open("testAlarms.txt", "r") | ||
#lines = file.read().split("\n") | ||
|
||
# Go through the report and create alarm objects distinguishing by their current alarm status. | ||
# Start looping from the last line in order to process the oldest alarms first. | ||
for line in reversed(lines): | ||
|
||
if 'Aktueller Status' in line: | ||
status = line[18:] | ||
indexOfQuote = status.index('"') | ||
status = status[:indexOfQuote] | ||
elif 'Kategorie' in line: | ||
kategorie = line[11:] | ||
elif 'Besttigt' in line: | ||
bestaetigtVon = line[10:] | ||
elif 'Quelle' in line: | ||
quelle = line[8:] | ||
elif '","' in line: | ||
parts = line.split(",") | ||
dateAndTime = parts[0].replace('"', '').split(" ") | ||
standort = parts[1].replace('"', '') | ||
message = parts[2].replace('"', '') | ||
|
||
date = dateAndTime[0] | ||
parts = date.split(".") | ||
day = int(parts[0]) | ||
month = int(parts[1]) | ||
year = int(parts[2]) | ||
#print(year,month,day) | ||
|
||
time = dateAndTime[1] | ||
parts = time.split(":") | ||
hours = int(parts[0]) | ||
minutes = int(parts[1]) | ||
seconds = int(parts[2]) | ||
#print(hours,minutes,seconds) | ||
|
||
date = datetime.datetime(year, month, day, hours, minutes, seconds) | ||
|
||
# Create the alarm object and add the unchecked/unsolved alarms to a list for observation | ||
if status == 'Normal': | ||
# Before appending the current alarm to the list of alarms check if this alarm is already contained | ||
# in the list: | ||
alarmAlreadyKnown = False | ||
for a in alarmsChecked: | ||
if a.quelle == quelle and a.date == date: | ||
# This alarm is already known; move on to the next alarm | ||
alarmAlreadyKnown = True | ||
break | ||
if not alarmAlreadyKnown: | ||
# Before appending the checked/solved alarm to the list, first check if this alarm is already | ||
# the check/solution to a prior alarm with status e.g. 'unnormal': | ||
removedAlarm = False | ||
for a in alarmsRunning: | ||
if a.quelle == quelle: | ||
# Remove alarm from running and do not append to checked | ||
removedAlarm = True | ||
alarmsRunning.remove(a) | ||
print('Removing alarm ' + str(date) + quelle + ' from alarmsRunning') | ||
if not removedAlarm: | ||
# This should actually not happen: to have an alarm with status 'Normal' but to not find an | ||
# appropriate alarm with status 'Unnormal' | ||
age = 0 | ||
alarmsChecked.append(alarm(date, age, standort, message, quelle, bestaetigtVon, kategorie, status)) | ||
else: | ||
# Before appending the current alarm to the list of alarms check if this alarm is already contained | ||
# in the list: | ||
alarmAlreadyKnown = False | ||
for a in alarmsRunning: | ||
if a.quelle == quelle and a.date == date: | ||
# This alarm is already known; move on to the next alarm | ||
alarmAlreadyKnown = True | ||
# Observe the age of the alarm, i.e, increase the age by the time interval in which new alarms are caught | ||
a.age += checkForNewAlarmsInterval | ||
break | ||
if not alarmAlreadyKnown: | ||
print('Appending alarm '+str(date)+quelle+' to alarmsRunning') | ||
age = 0 | ||
alarmsRunning.append(alarm(date, age, standort, message, quelle, bestaetigtVon, kategorie, status)) | ||
|
||
if alarmsChecked: | ||
for a in alarmsChecked: | ||
print(a.date, a.standort, a.message, a.quelle, a.bestaetigtVon, a.kategorie, a.status) | ||
else: | ||
print('No alarms in list alarmsChecked') | ||
|
||
if alarmsRunning: | ||
for a in alarmsRunning: | ||
print(a.date, a.standort, a.message, a.quelle, a.bestaetigtVon, a.kategorie, a.status) | ||
# Check the age of the still running alarms and take action in case of, for example, the age is greater than e.g. 20 min | ||
if a.age / 60 > 20: | ||
pass | ||
# send e-mail / SMS notification to ... | ||
else: | ||
print('No alarms in list alarmsRunning') | ||
|
||
sleep(checkForNewAlarmsInterval) | ||
|
||
|
||
if __name__=='__main__': | ||
if len(sys.argv) < 2: | ||
print "You haven't specified any arguments. Use -h to get more details on how to use this command." | ||
sys.exit(1) | ||
|
||
parser = argparse.ArgumentParser() | ||
parser.add_argument('--username', '-u', type=str, default=None, help='Username for the login to the WebCTRL server') | ||
parser.add_argument('--password', '-p', type=str, default=None, help='Password for the login to the WebCTRL server') | ||
parser.add_argument('--node', '-n', type=str, default='trees/geographic', | ||
help='Path to the point or node whose children you want to retrieve. Start querying at the lowest level with "-n /trees/geographic"') | ||
parser.add_argument('-url', type=str, default='https://webctrl.rz-berlin.mpg.de', | ||
help="URL of the WebCTRL server as e.g. http://google.de") | ||
parser.add_argument('-interval', '-i', type=int, default=60, help="Interval in SECONDS in which the script checks for new alarms") | ||
args = parser.parse_args() | ||
|
||
# Get the password if it hasn't been passed as argument | ||
if args.password is None: | ||
args.password = getpass.getpass('No password specified via -p. Please enter your WebCTRL login password: ') | ||
|
||
# Convert the argparse.Namespace to a dictionary via vars(args) | ||
main(vars(args)) | ||
sys.exit(0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import suds | ||
import sys | ||
import xml | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import suds | ||
import sys | ||
import xml | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import suds | ||
import sys | ||
import xml | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
import suds | ||
import sys | ||
import xml | ||
|