diff options
author | Joey Hagedorn <hagedorn@mcs.anl.gov> | 2006-11-22 21:10:33 +0000 |
---|---|---|
committer | Joey Hagedorn <hagedorn@mcs.anl.gov> | 2006-11-22 21:10:33 +0000 |
commit | ebf644b4c820244aad5019b5540ddac9401109de (patch) | |
tree | d6a9b703ae7a69824266526cf9258c9e8261075f | |
parent | 28f5be4543277452811492752d887dfd7030bfc5 (diff) | |
download | bcfg2-ebf644b4c820244aad5019b5540ddac9401109de.tar.gz bcfg2-ebf644b4c820244aad5019b5540ddac9401109de.tar.bz2 bcfg2-ebf644b4c820244aad5019b5540ddac9401109de.zip |
moving brpt to server-reports
git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@2520 ce84e21b-d406-0410-9b95-82705330c041
27 files changed, 25 insertions, 1502 deletions
diff --git a/reports/brpt/__init__.py b/reports/brpt/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/reports/brpt/__init__.py +++ /dev/null diff --git a/reports/brpt/backends.py b/reports/brpt/backends.py deleted file mode 100644 index 9207038ed..000000000 --- a/reports/brpt/backends.py +++ /dev/null @@ -1,35 +0,0 @@ -from django.contrib.auth.models import User -from nisauth import * - -class NISBackend(object): - - def authenticate(self, username=None, password=None): - try: - print "start nis authenticate" - n = nisauth(username, password) - temp_pass = User.objects.make_random_password(100) - nis_user = dict(username=username, - ) - - user_session_obj = dict( - email = username, - first_name = None, - last_name = None, - uid = n.uid - ) - user, created = User.objects.get_or_create(username=username) - - return user - - except NISAUTHError, e: - print str(e) - return None - - - def get_user(self, user_id): - try: - return User.objects.get(pk=user_id) - except User.DoesNotExist, e: - print str(e) - return None - diff --git a/reports/brpt/importscript.py b/reports/brpt/importscript.py deleted file mode 100755 index 252fce886..000000000 --- a/reports/brpt/importscript.py +++ /dev/null @@ -1,285 +0,0 @@ -#! /usr/bin/env python -'''Imports statistics.xml and clients.xml files in to database backend for new statistics engine''' -__revision__ = '$Revision$' - -import os, sys -try: - import settings -except ImportError: - try: - import brpt.settings - except ImportError: - sys.stderr.write("Failed to locate settings.py. Is brpt python module installed?") - sys.exit(1) - -project_directory = os.path.dirname(settings.__file__) -project_name = os.path.basename(project_directory) -sys.path.append(os.path.join(project_directory, '..')) -project_module = __import__(project_name, '', '', ['']) -sys.path.pop() -# Set DJANGO_SETTINGS_MODULE appropriately. -os.environ['DJANGO_SETTINGS_MODULE'] = '%s.settings' % project_name - -from brpt.reports.models import Client, Interaction, Bad, Modified, Extra, Performance, Reason -from lxml.etree import XML, XMLSyntaxError -from sys import argv -from getopt import getopt, GetoptError -from datetime import datetime -from time import strptime, sleep -from django.db import connection, backend -import ConfigParser - -if __name__ == '__main__': - somewhatverbose = False - verbose = False - veryverbose = False - - try: - opts, args = getopt(argv[1:], "hvudc:s:", ["help", "verbose", "updates" ,"debug", "clients=", "stats="]) - except GetoptError, mesg: - # print help information and exit: - print "%s\nUsage:\nimportscript.py [-h] [-v] [-u] [-d] [-C bcfg2 config file] [-c clients-file] [-s statistics-file]" % (mesg) - raise SystemExit, 2 - opts.append(("1","1"))#this requires the loop run at least once - for o, a in opts: - if o in ("-h", "--help"): - print "Usage:\nimportscript.py [-h] [-v] -c <clients-file> -s <statistics-file> \n" - print "h : help; this message" - print "v : verbose; print messages on record insertion/skip" - print "u : updates; print status messages as items inserted semi-verbose" - print "d : debug; print most SQL used to manipulate database" - print "C : path to bcfg2.conf config file." - print "c : clients.xml file" - print "s : statistics.xml file" - raise SystemExit - if o in ("-C"): - cpath = a - else: - cpath = "/etc/bcfg2.conf" - - cf = ConfigParser.ConfigParser() - cf.read([cpath]) - - if o in ("-v", "--verbose"): - verbose = True - if o in ("-u", "--updates"): - somewhatverbose = True - if o in ("-d", "--debug"): - veryverbose = True - if o in ("-c", "--clients"): - clientspath = a - else: - try: - clientspath = "%s/Metadata/clients.xml"%cf.get('server', 'repository') - except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): - print "Could not read bcfg2.conf; exiting" - raise SystemExit, 1 - - if o in ("-s", "--stats"): - statpath = a - else: - try: - statpath = "%s/etc/statistics.xml"%cf.get('server', 'repository') - except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): - print "Could not read bcfg2.conf; exiting" - raise SystemExit, 1 - - '''Reads Data & Config files''' - try: - statsdata = XML(open(statpath).read()) - except (IOError, XMLSyntaxError): - print("StatReports: Failed to parse %s"%(statpath)) - raise SystemExit, 1 - try: - clientsdata = XML(open(clientspath).read()) - except (IOError, XMLSyntaxError): - print("StatReports: Failed to parse %s"%(clientspath)) - raise SystemExit, 1 - - cursor = connection.cursor() - clients = {} - cursor.execute("SELECT name, id from reports_client;") - [clients.__setitem__(a,b) for a,b in cursor.fetchall()] - - for node in statsdata.findall('Node'): - name = node.get('name') - if not clients.has_key(name): - cursor.execute("INSERT INTO reports_client VALUES (NULL, %s, %s, NULL, NULL)", [datetime.now(),name]) - clients[name] = cursor.lastrowid - if verbose: - print("Client %s added to db"%name) - else: - if verbose: - print("Client %s already exists in db"%name) - - - cursor.execute("SELECT client_id, timestamp, id from reports_interaction") - interactions_hash = {} - [interactions_hash.__setitem__(str(x[0])+"-"+x[1].isoformat(),x[2]) for x in cursor.fetchall()]#possibly change str to tuple - pingability = {} - [pingability.__setitem__(n.get('name'),n.get('pingable',default='N')) for n in clientsdata.findall('Client')] - - - cursor.execute("SELECT id, owner, current_owner, %s, current_group, perms, current_perms, status, current_status, %s, current_to, version, current_version, current_exists, current_diff from reports_reason"%(backend.quote_name("group"),backend.quote_name("to"))) - reasons_hash = {} - [reasons_hash.__setitem__(tuple(n[1:]),n[0]) for n in cursor.fetchall()] - - cursor.execute("SELECT id, name, kind, reason_id from reports_bad") - bad_hash = {} - [bad_hash.__setitem__((n[1],n[2],n[3]),n[0]) for n in cursor.fetchall()] - - cursor.execute("SELECT id, name, kind, reason_id from reports_extra") - extra_hash = {} - [extra_hash.__setitem__((n[1],n[2],n[3]),n[0]) for n in cursor.fetchall()] - - cursor.execute("SELECT id, name, kind, reason_id from reports_modified") - modified_hash = {} - [modified_hash.__setitem__((n[1],n[2],n[3]),n[0]) for n in cursor.fetchall()] - - cursor.execute("SELECT id, metric, value from reports_performance") - performance_hash = {} - [performance_hash.__setitem__((n[1],n[2]),n[0]) for n in cursor.fetchall()] - - cursor.execute("SELECT x.client_id, reports_ping.status from (SELECT client_id, MAX(endtime) from reports_ping GROUP BY client_id) x, reports_ping WHERE x.client_id = reports_ping.client_id") - ping_hash = {} - [ping_hash.__setitem__(n[0],n[1]) for n in cursor.fetchall()] - - - for r in statsdata.findall('.//Bad/*')+statsdata.findall('.//Extra/*')+statsdata.findall('.//Modified/*'): - arguments = [r.get('owner', default=""), r.get('current_owner', default=""), - r.get('group', default=""), r.get('current_group', default=""), - r.get('perms', default=""), r.get('current_perms', default=""), - r.get('status', default=""), r.get('current_status', default=""), - r.get('to', default=""), r.get('current_to', default=""), - r.get('version', default=""), r.get('current_version', default=""), - (r.get('current_exists', default="True").capitalize()=="True"), - r.get('current_diff', default="")] - if reasons_hash.has_key(tuple(arguments)): - current_reason_id = reasons_hash[tuple(arguments)] - if verbose: - print("Reason already exists..... It's ID is: %s"%current_reason_id) - else: - cursor.execute("INSERT INTO reports_reason VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s);", - arguments) - current_reason_id = cursor.lastrowid - reasons_hash[tuple(arguments)] = current_reason_id - if verbose: - print("Reason inserted with id %s"%current_reason_id) - if (somewhatverbose or verbose): - print "----------------REASONS SYNCED---------------------" - - for node in statsdata.findall('Node'): - name = node.get('name') - try: - pingability[name] - except KeyError: - pingability[name] = 'N' - for statistics in node.findall('Statistics'): - t = strptime(statistics.get('time')) - timestamp = datetime(t[0],t[1],t[2],t[3],t[4],t[5])#Maybe replace with django.core.db typecasts typecast_timestamp()? import from django.backends util - if interactions_hash.has_key(str(clients[name]) +"-"+ timestamp.isoformat()): - current_interaction_id = interactions_hash[str(clients[name])+"-"+timestamp.isoformat()] - if verbose: - print("Interaction for %s at %s with id %s already exists"%(clients[name], - datetime(t[0],t[1],t[2],t[3],t[4],t[5]),current_interaction_id)) - else: - cursor.execute("INSERT INTO reports_interaction VALUES (NULL, %s, %s, %s, %s, %s, %s, %s);", - [clients[name], timestamp, - statistics.get('state', default="unknown"), statistics.get('revision',default="unknown"), - statistics.get('client_version',default="unknown"), - statistics.get('good',default="0"), statistics.get('total',default="0")]) - current_interaction_id = cursor.lastrowid - interactions_hash[str(clients[name])+"-"+timestamp.isoformat()] = current_interaction_id - if verbose: - print("Interaction for %s at %s with id %s INSERTED in to db"%(clients[name], - timestamp, current_interaction_id)) - - - for (xpath, hashname, tablename) in [('Bad/*', bad_hash, 'reports_bad'), - ('Extra/*', extra_hash, 'reports_extra'), - ('Modified/*', modified_hash, 'reports_modified')]: - for x in statistics.findall(xpath): - arguments = [x.get('owner', default=""), x.get('current_owner', default=""), - x.get('group', default=""), x.get('current_group', default=""), - x.get('perms', default=""), x.get('current_perms', default=""), - x.get('status', default=""), x.get('current_status', default=""), - x.get('to', default=""), x.get('current_to', default=""), - x.get('version', default=""), x.get('current_version', default=""), - (x.get('current_exists', default="True").capitalize()=="True"), - x.get('current_diff', default="")] - - if not hashname.has_key((x.get('name'), x.tag, reasons_hash[tuple(arguments)])): - cursor.execute("INSERT INTO "+tablename+" VALUES (NULL, %s, %s, %s, %s);", - [x.get('name'), - x.tag, - (x.get('critical', default="False").capitalize()=="True"), - reasons_hash[tuple(arguments)]]) - item_id = cursor.lastrowid - hashname[(x.get('name'), x.tag, reasons_hash[tuple(arguments)])] = item_id - if verbose: - print "Bad item INSERTED having reason id %s and ID %s"%(reasons_hash[tuple(arguments)], - hashname[(x.get('name'),x.tag, reasons_hash[tuple(arguments)])]) - else: - item_id = hashname[(x.get('name'), x.tag, reasons_hash[tuple(arguments)])] - if verbose: - print "Bad item exists, has reason id %s and ID %s"%(reasons_hash[tuple(arguments)], - hashname[(x.get('name'),x.tag, reasons_hash[tuple(arguments)])]) - try: - cursor.execute("INSERT INTO "+tablename+"_interactions VALUES (NULL, %s, %s);", - [item_id, current_interaction_id]) - except: - pass - - for times in statistics.findall('OpStamps'): - for tags in times.items(): - if not performance_hash.has_key((tags[0],float(tags[1]))): - cursor.execute("INSERT INTO reports_performance VALUES (NULL, %s, %s)",[tags[0],tags[1]]) - performance_hash[(tags[0],tags[1])] = cursor.lastrowid - else: - item_id = performance_hash[(tags[0],float(tags[1]))] - #already exists - try: - cursor.execute("INSERT INTO reports_performance_interaction VALUES (NULL, %s, %s);", - [item_id, current_interaction_id]) - except: - pass - - if (somewhatverbose or verbose): - print("----------------INTERACTIONS SYNCED----------------") - cursor.execute("select reports_interaction.id, x.client_id from (select client_id, MAX(timestamp) as timer from reports_interaction Group BY client_id) x, reports_interaction where reports_interaction.client_id = x.client_id AND reports_interaction.timestamp = x.timer") - for row in cursor.fetchall(): - cursor.execute("UPDATE reports_client SET current_interaction_id = %s where reports_client.id = %s", - [row[0],row[1]]) - if (somewhatverbose or verbose): - print("------------LATEST INTERACTION SET----------------") - - for key in pingability.keys(): - if clients.has_key(key): - if ping_hash.has_key(clients[key]): - if ping_hash[clients[key]] == pingability[key]: - cursor.execute("UPDATE reports_ping SET endtime = %s where reports_ping.client_id = %s", - [datetime.now(),clients[key]]) - else: - ping_hash[clients[key]] = pingability[key] - cursor.execute("INSERT INTO reports_ping VALUES (NULL, %s, %s, %s, %s)", - [clients[key], datetime.now(), datetime.now(), pingability[key]]) - else: - ping_hash[clients[key]] = pingability[key] - cursor.execute("INSERT INTO reports_ping VALUES (NULL, %s, %s, %s, %s)", - [clients[key], datetime.now(), datetime.now(), pingability[key]]) - - if (somewhatverbose or verbose): - print "---------------PINGDATA SYNCED---------------------" - - connection._commit() - #Clients are consistent - if veryverbose: - for q in connection.queries: - if not (q['sql'].startswith('INSERT INTO reports_bad_interactions')| - q['sql'].startswith('INSERT INTO reports_extra_interactions')| - q['sql'].startswith('INSERT INTO reports_performance_interaction')| - q['sql'].startswith('INSERT INTO reports_modified_interactions')| - q['sql'].startswith('UPDATE reports_client SET current_interaction_id ')): - print q - - raise SystemExit, 0 diff --git a/reports/brpt/manage.py b/reports/brpt/manage.py deleted file mode 100755 index 5e78ea979..000000000 --- a/reports/brpt/manage.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python -from django.core.management import execute_manager -try: - import settings # Assumed to be in the same directory. -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) - sys.exit(1) - -if __name__ == "__main__": - execute_manager(settings) diff --git a/reports/brpt/nisauth.py b/reports/brpt/nisauth.py deleted file mode 100644 index e9a954cd8..000000000 --- a/reports/brpt/nisauth.py +++ /dev/null @@ -1,43 +0,0 @@ -import os -import crypt, nis -import brpt.settings import AUTHORIZED_GROUP - -"""Checks with NIS to see if the current user is in the support group""" - -__revision__ = "$Revision: $" - -class NISAUTHError(Exception): - """NISAUTHError is raised when somehting goes boom.""" - pass - -class nisauth(object): - group_test = False - samAcctName = None - distinguishedName = None - sAMAccountName = None - telephoneNumber = None - title = None - memberOf = None - department = None #this will be a list - mail = None - extensionAttribute1 = None #badgenumber - badge_no = None - uid = None - - def __init__(self,login,passwd=None): - """get user profile from NIS""" - try: - p = nis.match(login, 'passwd.byname').split(":") - print p - except: - raise NISAUTHError('username') - # check user password using crypt and 2 character salt from passwd file - if p[1] == crypt.crypt(passwd, p[1][:2]): - # check to see if user is in valid support groups - # will have to include these groups in a settings file eventually - if not login in nis.match(AUTHORIZED_GROUP, 'group.byname').split(':')[-1].split(','): - raise NISAUTHError('group') - self.uid = p[2] - print self.uid - else: - raise NISAUTHError('password') diff --git a/reports/brpt/reports/__init__.py b/reports/brpt/reports/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/reports/brpt/reports/__init__.py +++ /dev/null diff --git a/reports/brpt/reports/models.py b/reports/brpt/reports/models.py deleted file mode 100644 index dff68d272..000000000 --- a/reports/brpt/reports/models.py +++ /dev/null @@ -1,236 +0,0 @@ -'''Django models for BCFG reports''' -from django.db import models -from datetime import datetime, timedelta - -KIND_CHOICES = ( - #These are the kinds of config elements - ('ConfigFile', 'ConfigFile'), - ('Package', 'Package'), - ('Service', 'Service'), - ('SymLink', 'SymLink'), - ('Directory', 'Directory'), - ('Permissions','Permissions'), -) -PING_CHOICES = ( - #These are possible ping states - ('Up (Y)', 'Y'), - ('Down (N)', 'N') -) -class Client(models.Model): - '''object representing every client we have seen stats for''' - creation = models.DateTimeField() - name = models.CharField(maxlength=128, core=True) - current_interaction = models.ForeignKey('Interaction', - null=True, blank=True, - related_name="parent_client") - expiration = models.DateTimeField(blank=True, null=True) - - def __str__(self): - return self.name - - class Admin: - pass - -class Metadata(models.Model): - '''insert magical interface to client metadata here''' - client = models.ForeignKey(Client) - timestamp = models.DateTimeField() - def __str__(self): - return self.timestamp - -class Repository(models.Model): - '''insert magical interface to subversioned repository here''' - timestamp = models.DateTimeField() - def __str__(self): - return self.timestamp - -class Ping(models.Model): - '''represents a ping of a client (sparsely)''' - client = models.ForeignKey(Client, related_name="pings") - starttime = models.DateTimeField() - endtime = models.DateTimeField() - status = models.CharField(maxlength=4, choices=PING_CHOICES)#up/down - - class Meta: - get_latest_by = 'endtime' - -class InteractiveManager(models.Manager): - '''manages interactions objects''' - - '''returns most recent interaction as of specified timestamp in format: - '2006-01-01 00:00:00' or 'now' or None->'now' ''' - def interaction_per_client(self, maxdate = None): - from django.db import connection - cursor = connection.cursor() - - #in order to prevent traceback when zero records are returned. - #this could mask some database errors - try: - if (maxdate == 'now' or maxdate == None): - cursor.execute("select reports_interaction.id, x.client_id from (select client_id, MAX(timestamp) "+ - "as timer from reports_interaction GROUP BY client_id) x, reports_interaction where "+ - "reports_interaction.client_id = x.client_id AND reports_interaction.timestamp = x.timer") - else: - cursor.execute("select reports_interaction.id, x.client_id from (select client_id, timestamp, MAX(timestamp) "+ - "as timer from reports_interaction WHERE timestamp < %s GROUP BY client_id) x, reports_interaction where "+ - "reports_interaction.client_id = x.client_id AND reports_interaction.timestamp = x.timer", - [maxdate]) - in_idents = [item[0] for item in cursor.fetchall()] - except: - in_idents = [] - return self.filter(id__in = in_idents) - - -class Interaction(models.Model): - '''Models each reconfiguration operation interaction between client and server''' - client = models.ForeignKey(Client, related_name="interactions", core=True) - timestamp = models.DateTimeField()#Timestamp for this record - state = models.CharField(maxlength=32)#good/bad/modified/etc - repo_revision = models.IntegerField()#repo revision at time of interaction - client_version = models.CharField(maxlength=32)#Client Version - goodcount = models.IntegerField()#of good config-items - totalcount = models.IntegerField()#of total config-items - - def __str__(self): - return "With " + self.client.name + " @ " + self.timestamp.isoformat() - - def percentgood(self): - if not self.totalcount == 0: - return (self.goodcount/float(self.totalcount))*100 - else: - return 0 - - def percentbad(self): - if not self.totalcount == 0: - return ((self.totalcount-self.goodcount)/(float(self.totalcount)))*100 - else: - return 0 - - def isclean(self): - if (self.bad_items.count() == 0 and self.goodcount == self.totalcount): - #if (self.state == "good"): - return True - else: - return False - - def isstale(self): - if (self == self.client.current_interaction):#Is Mostrecent - if(datetime.now()-self.timestamp > timedelta(hours=25) ): - return True - else: - return False - else: - #Search for subsequent Interaction for this client - #Check if it happened more than 25 hrs ago. - if (self.client.interactions.filter(timestamp__gt=self.timestamp) - .order_by('timestamp')[0].timestamp - - self.timestamp > timedelta(hours=25)): - return True - else: - return False - def save(self): - super(Interaction, self).save() #call the real save... - self.client.current_interaction = self.client.interactions.latest() - self.client.save()#save again post update - - objects = InteractiveManager() - - class Admin: - list_display = ('client', 'timestamp', 'state') - list_filter = ['client', 'timestamp'] - pass - class Meta: - get_latest_by = 'timestamp' - -class Reason(models.Model): - '''reason why modified or bad entry did not verify, or changed''' - owner = models.TextField(maxlength=128, blank=True) - current_owner = models.TextField(maxlength=128, blank=True) - group = models.TextField(maxlength=128, blank=True) - current_group = models.TextField(maxlength=128, blank=True) - perms = models.TextField(maxlength=4, blank=True)#txt fixes typing issue - current_perms = models.TextField(maxlength=4, blank=True) - status = models.TextField(maxlength=3, blank=True)#on/off/(None) - current_status = models.TextField(maxlength=1, blank=True)#on/off/(None) - to = models.TextField(maxlength=256, blank=True) - current_to = models.TextField(maxlength=256, blank=True) - version = models.TextField(maxlength=128, blank=True) - current_version = models.TextField(maxlength=128, blank=True) - current_exists = models.BooleanField()#False means its missing. Default True - current_diff = models.TextField(maxlength=1280, blank=True) - def _str_(self): - return "Reason" - -class Modified(models.Model): - '''Modified configuration element''' - interactions = models.ManyToManyField(Interaction, related_name="modified_items") - name = models.CharField(maxlength=128, core=True) - kind = models.CharField(maxlength=16, choices=KIND_CHOICES) - critical = models.BooleanField() - reason = models.ForeignKey(Reason) - def __str__(self): - return self.name - -class Extra(models.Model): - '''Extra configuration element''' - interactions = models.ManyToManyField(Interaction, related_name="extra_items") - name = models.CharField(maxlength=128, core=True) - kind = models.CharField(maxlength=16, choices=KIND_CHOICES) - critical = models.BooleanField() - reason = models.ForeignKey(Reason) - def __str__(self): - return self.name - -class Bad(models.Model): - '''Bad configuration element''' - interactions = models.ManyToManyField(Interaction, related_name="bad_items") - name = models.CharField(maxlength=128, core=True) - kind = models.CharField(maxlength=16, choices=KIND_CHOICES) - critical = models.BooleanField() - reason = models.ForeignKey(Reason) - def __str__(self): - return self.name - -class PerformanceManager(models.Manager): - '''Provides ability to effectively query for performance information - It is possible this should move to the view''' - #Date format for maxdate: '2006-01-01 00:00:00' - def performance_per_client(self, maxdate = None): - from django.db import connection - cursor = connection.cursor() - if (maxdate == 'now' or maxdate == None): - cursor.execute("SELECT reports_client.name, reports_performance.metric, reports_performance.value "+ - "FROM reports_performance, reports_performance_interaction, reports_client WHERE ( "+ - "reports_client.current_interaction_id = reports_performance_interaction.interaction_id AND "+ - "reports_performance.id = reports_performance_interaction.performance_id)") - else: - cursor.execute("select reports_client.name, reports_performance.metric, "+ - "reports_performance.value from (Select reports_interaction.client_id as client_id, "+ - "MAX(reports_interaction.timestamp) as timestamp from reports_interaction where "+ - "timestamp < %s GROUP BY reports_interaction.client_id) x, reports_client, "+ - "reports_interaction, reports_performance, reports_performance_interaction where "+ - "reports_client.id = x.client_id AND x.timestamp = reports_interaction.timestamp AND "+ - "x.client_id = reports_interaction.client_id AND reports_performance.id = "+ - "reports_performance_interaction.performance_id AND "+ - "reports_performance_interaction.interaction_id = reports_interaction.id", [maxdate]) - - results = {} - for row in cursor.fetchall(): - try: - results[row[0]].__setitem__(row[1], row[2]) - except KeyError: - results[row[0]] = {row[1]:row[2]} - - return results - -#performance metrics, models a performance-metric-item -class Performance(models.Model): - '''Object representing performance data for any interaction''' - interaction = models.ManyToManyField(Interaction, related_name="performance_items") - metric = models.CharField(maxlength=128, core=True) - value = models.FloatField(max_digits=32, decimal_places=16) - def __str__(self): - return self.metric - - objects = PerformanceManager() - diff --git a/reports/brpt/reports/sql/client.sql b/reports/brpt/reports/sql/client.sql deleted file mode 100644 index 6ef37a27f..000000000 --- a/reports/brpt/reports/sql/client.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE VIEW reports_current_interactions AS SELECT x.client_id AS client_id, reports_interaction.id AS interaction_id FROM (select client_id, MAX(timestamp) as timer FROM reports_interaction GROUP BY client_id) x, reports_interaction WHERE reports_interaction.client_id = x.client_id AND reports_interaction.timestamp = x.timer
\ No newline at end of file diff --git a/reports/brpt/reports/templates/base.html b/reports/brpt/reports/templates/base.html deleted file mode 100644 index 1bee97206..000000000 --- a/reports/brpt/reports/templates/base.html +++ /dev/null @@ -1,45 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> -<head> - <title>{% block title %}Bcfg2 Reporting System{% endblock %}</title> - <link rel="stylesheet" type="text/css" href="/site_media/boxypastel.css" /> - <link rel="stylesheet" type="text/css" href="/site_media/base.css" /> - <script type="text/javascript" src="/site_media/main.js"> - </script> - {% block extra_header_info %}{% endblock %} -</head> - -<body> - <div id="header"> - <div id="branding"> - <h1>Bcfg2 Reporting System</h1> - </div> - <div id="user-tools">...Change is Coming...</div> - </div> - <div id="sidebar"> - {% block sidebar %} - <ul class="sidebar"> - <li><a href="/" class="sidebar">Home</a></li> - <li><a href="/clients/" class="sidebar">Clients</a></li> - <li> - <a href="/displays/" class="sidebar">Displays</a> - <ul class="sidebar-level2"> - <li><a href="/displays/sys-view/" class="sidebar">System</a></li> - <li><a href="/displays/summary/" class="sidebar">Summary</a></li> - <li><a href="/displays/timing/" class="sidebar">Timing</a></li> - </ul> - </li> - </ul> - {% endblock %} - </div> - - <div id="content-main"> - <div id="container"> - {% block pagebanner %}{% endblock %} - {% block content %}{% endblock %} - - </div> - </div> -</body> -</html>
\ No newline at end of file diff --git a/reports/brpt/reports/templates/clients/client-nodebox.html b/reports/brpt/reports/templates/clients/client-nodebox.html deleted file mode 100644 index dade598cf..000000000 --- a/reports/brpt/reports/templates/clients/client-nodebox.html +++ /dev/null @@ -1,63 +0,0 @@ -{% load django_templating_sigh %} -{% if client %} - <a name="{{client.name}}"></a> - <div class="nodebox" name="{{client.name}}"> - <span class="notebox">Time Ran: {{interaction.timestamp}}</span> - <!--<span class="configbox">(-Insert Profile Name Here-)</span>--> - - <table class="invisitable"> - <tr><td width="43%"><h2>Node: <span class="nodename"> - <a href="/clients/{{client.name}}/{{interaction.id}}">{{client.name}}</a></span></h2></td> - <td width="23%"> - {% if interaction.repo_revision %}Revision: {{interaction.repo_revision}}{% endif %} - </td> - <td width="33%"><div class="statusborder"> - <div class="greenbar" style="width: {{interaction.percentgood}}%;"> </div> - <div class="redbar" style="width: {{interaction.percentbad}}%;"> </div> - </div> - </td></tr> - </table> - {% if interaction.isclean %} - <div class="clean"> - <span class="nodelisttitle">Node is clean; Everything has been satisfactorily configured.</span> - </div> - {% endif %} - {% if interaction.isstale %} - <div class="warning"> - <span class="nodelisttitle">This node did not run within the last 24 hours-- it may be out of date.</span> - </div> - {% endif %} - {% if interaction.bad_items.all %} - <div class="bad"> - <span class="nodelisttitle"><a href="javascript:toggleLayer('{{client.name}}-bad');" title="Click to expand" class="commentLink">{{interaction.bad_items.count}}</a> items did not verify and are considered Dirty.<br /></span> - <div class="items" id="{{client.name}}-bad"><ul class="plain"> - {% for bad in interaction.bad_items.all|sortwell %} - <li><strong>{{bad.kind}}: </strong><tt><a href="/elements/bad/{{bad.id}}">{{bad.name}}</a></tt></li> - {% endfor %} - </ul></div> - </div> - {% endif %} - {% if interaction.modified_items.all %} - <div class="modified"> - <span class="nodelisttitle"><a href="javascript:toggleLayer('{{client.name}}-modified');" title="Click to expand" class="commentLink">{{interaction.modified_items.count}}</a> items were modified in the last run.<br /></span> - <div class="items" id="{{client.name}}-modified"><ul class="plain"> - {% for modified in interaction.modified_items.all|sortwell %} - <li><strong>{{modified.kind}}: </strong><tt><a href="/elements/modified/{{modified.id}}">{{modified.name}}</a></tt></li> - {% endfor %} - </ul></div> - </div> - {% endif %} - {% if interaction.extra_items.all %} - <div class="extra"> - <span class="nodelisttitle"><a href="javascript:toggleLayer('{{client.name}}-extra');" title="Click to expand" class="commentLink">{{interaction.extra_items.count}}</a> extra configuration elements on the node.<br /></span> - <div class="items" id="{{client.name}}-extra"><ul class="plain"> - {% for extra in interaction.extra_items.all|sortwell %} - <li><strong>{{extra.kind}}: </strong><tt>{{extra.name}}</tt></li> - {% endfor %} - </ul></div> - </div> - {% endif %} - </div> -{% else %} - <p>No record could be found for this client.</p> -{% endif %} diff --git a/reports/brpt/reports/templates/clients/detail.html b/reports/brpt/reports/templates/clients/detail.html deleted file mode 100644 index 4ac2123c1..000000000 --- a/reports/brpt/reports/templates/clients/detail.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Info for: {{client.name}}{% endblock %} - -{% block content %} -<b>Select time: </b> -<select name=quick onChange="MM_jumpMenu('parent',this,0)"> - {% for i in client.interactions.all %} - <option {% ifequal i.id interaction.id %}selected {% endifequal %} value="/clients/{{client.name}}/{{i.id}}/"> {{i.timestamp}} - {% endfor %} -</select> - -{% include "clients/client-nodebox.html" %} -{% endblock %} diff --git a/reports/brpt/reports/templates/clients/index.html b/reports/brpt/reports/templates/clients/index.html deleted file mode 100644 index 9870e2942..000000000 --- a/reports/brpt/reports/templates/clients/index.html +++ /dev/null @@ -1,36 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Client Index Listing{% endblock %} - -{% block pagebanner %} - <div class="header"> - <h1>Clients List</h1> - </div> - <br/> -{% endblock %} - -{% block content %} -{% if client_list_a %} -<table><tr><td align="top"> - <ul style="list-style-type:none;"> - {% for client in client_list_a %} - <li><div class="{{client.current_interaction.state}}-lineitem"> - <a href="{{client.name}}/">{{ client.name }}</a> - </div></li> - {% endfor %} - </ul> -</td><td align="top"> - <ul style="list-style-type:none;"> - {% if client_list_b %} - {% for client in client_list_b %} - <li><div class="{{client.current_interaction.state}}-lineitem"> - <a href="{{client.name}}/">{{ client.name }}</a> - </div></li> - {% endfor %} - {% endif %} - </ul> -</tr></tab.e> -{% else %} - <p>No client records are available.</p> -{% endif %} -{% endblock %} diff --git a/reports/brpt/reports/templates/config_items/index.html b/reports/brpt/reports/templates/config_items/index.html deleted file mode 100644 index 952172715..000000000 --- a/reports/brpt/reports/templates/config_items/index.html +++ /dev/null @@ -1,77 +0,0 @@ -{% extends "base.html" %} - -{% block extra_header_info %} -<script type="text/javascript" src="/site_media/CalendarPopup.js"></script> -<script language="JavaScript">var cal = new CalendarPopup();</script> -{% endblock%} -{% block title %}Configuration Element Details{% endblock %} - -{% block pagebanner %} - <div class="header"> - <h1>Configuration Element Details</h1> - </div> - <br/> -{% endblock %} - -{% block content %} -{% ifequal mod_or_bad "bad" %} -<div class="bad"> -<h2>Bad {{item.kind}}: {{item.name}}</h2> -</div> -{% else %} -<div class="modified"> -<h2>Modified {{item.kind}}: {{item.name}}</h2> -</div> -{% endifequal %} -<center> -<table border=1 padding=0 > -<tr><th>Reason</th><th>Current Status</th><th>Specified in BCFG</th></tr> -{% if item.reason.current_owner %} -<tr><td align="right"><b>Owner: </b></td><td>{{item.reason.owner}}</td><td>{{item.reason.current_owner}}</td></tr> -{% endif %}{% if item.reason.current_group %} -<tr><td align="right"><b>Group: </b></td><td>{{item.reason.group}}</td><td>{{item.reason.current_group}}</td></tr> -{% endif %}{% if item.reason.current_perms %} -<tr><td align="right"><b>Permissions: </b></td><td>{{item.reason.perms}}</td><td>{{item.reason.current_perms}}</td></tr> -{% endif %}{% if item.reason.current_status %} -<tr><td align="right"><b>Status: </b></td><td>{{item.reason.status}}</td><td>{{item.reason.current_status}}</td></tr> -{% endif %}{% if item.reason.current_to %} -<tr><td align="right"><b>Link Destination: </b></td><td>{{item.reason.to}}</td><td>{{item.reason.current_to}}</td></tr> -{% endif %}{% if item.reason.current_version %} -<tr><td align="right"><b>Version: </b></td><td>{{item.reason.version}}</td><td>{{item.reason.current_version}}</td></tr> -{% endif %}{% if not item.reason.current_exists %} -<tr><td align="right"><b>Existance: </b></td><td colspan=2>This item does not currently exist on the host but is specified to exist in the configuration.</td></tr> -{% endif %}{% if item.reason.current_diff %} -<tr><td align="right"><b>Unified Diff: </b></td><td colspan=2><pre>{{item.reason.current_diff}}</pre></td></tr> -{% endif %} -</table></center> -<hr/> -<div> -<span class="mini-date"> -<b>Enter date or use calendar popup: </b> -<form name="timestamp-select"> -<input type="text" name="date1" value="{{timestamp_date}}" size=10>@ -<input type="text" name="time" value="{{timestamp_time}}" size=8> -<a href="" onClick="cal.select(document.forms['timestamp-select'].date1,'anchor1','yyyy-MM-dd'); return false;" - name="anchor1" ID="anchor1">Calendar</A> -<input type="button" name="go" value="Go" onClick="location.href='/elements/{{mod_or_bad}}/{{item.id}}/'+document.forms['timestamp-select'].date1.value+'@'+document.forms['timestamp-select'].time.value;" /> - | <input type="button" name="now" value="Now" onClick="location.href='/elements/{{mod_or_bad}}/{{item.id}}';"/> -</form> -</span><br/><br/><br/></div> -{% if associated_client_list %} - <p>The following clients had this problem as of {{timestamp_date}}@{{timestamp_time}}:</p> - {% for client in associated_client_list %} - <a href="/clients/{{client.name}}">{{client.name}}</a><br/> - {% endfor %} - <br /> - <br /> -{% else %} - <p>No Clients had this problem at {{timestamp}}</p> -{% endif %} - - - - - - - -{% endblock %} diff --git a/reports/brpt/reports/templates/displays/index.html b/reports/brpt/reports/templates/displays/index.html deleted file mode 100644 index 5d1d3bf76..000000000 --- a/reports/brpt/reports/templates/displays/index.html +++ /dev/null @@ -1,18 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Display Index Listing{% endblock %} -{% block pagebanner %} - <div class="header"> - <h1>BCFG Display Index</h1> - {% comment %} <span class="notebox">Report Run @ {% now "F j, Y P"%}</span>{% endcomment %} - </div> - <br/> -{% endblock %} - -{% block content %} -<ul> -<li><a href="/displays/sys-view/">System View</a></li> -<li><a href="/displays/summary/">Summary Only</a></li> -<li><a href="/displays/timing/">Timing</a></li> -</ul> -{% endblock %} diff --git a/reports/brpt/reports/templates/displays/summary-block-direct-links.html b/reports/brpt/reports/templates/displays/summary-block-direct-links.html deleted file mode 100644 index a218e12b6..000000000 --- a/reports/brpt/reports/templates/displays/summary-block-direct-links.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends "displays/summary-block.html" %} -{% block linkprefix1 %}/clients/{% endblock %} -{% block linkprefix2 %}/clients/{% endblock %} -{% block linkprefix3 %}/clients/{% endblock %} -{% block linkprefix4 %}/clients/{% endblock %} -{% block linkprefix5 %}/clients/{% endblock %} -{% block linkprefix6 %}/clients/{% endblock %}
\ No newline at end of file diff --git a/reports/brpt/reports/templates/displays/summary-block.html b/reports/brpt/reports/templates/displays/summary-block.html deleted file mode 100644 index a42176183..000000000 --- a/reports/brpt/reports/templates/displays/summary-block.html +++ /dev/null @@ -1,90 +0,0 @@ -{% load django_templating_sigh %} - - <div class="nodebox"> - <h2>Summary:</h2> - <p class="indented">{{client_list|length }} Nodes were included in your report.</p> - {% if clean_client_list %} - <div class="clean"> - <span class="nodelisttitle"><a href="javascript:toggleLayer('goodsummary');" title="Click to Expand" class="commentLink">{{clean_client_list|length}}</a> nodes are clean.<br /></span> - <div class="items" id="goodsummary"><ul class="plain"> - {% for client in clean_client_list|sortname %} - {% set_interaction "foo" %} - <li><b>Node: </b></tt> - <tt><a href="{% block linkprefix1 %}#{% endblock %}{{client.name}}">{{client.name}}</a></tt><span class="mini-date">{{interaction.timestamp}}</span></li> - {% endfor %} - </ul></div> - </div> - {% endif %} - {% if bad_client_list %} - <div class="bad"> - <span class="nodelisttitle"><a href="javascript:toggleLayer('badsummary');" title="Click to Expand" class="commentLink">{{bad_client_list|length}}</a> nodes are bad.<br /></span> - <div class="items" id="badsummary"><ul class="plain"> - {% for client in bad_client_list|sortname %} - {% set_interaction "foo" %} - <li><b>Node: </b></tt> - <tt><a href="{% block linkprefix2 %}#{% endblock %}{{client.name}}">{{client.name}}</a></tt><span class="mini-date">{{interaction.timestamp}}</span></li> - {% endfor %} - </ul></div> - </div> - {% endif %} - {% if modified_client_list %} - <div class="modified"> - <span class="nodelisttitle"><a href="javascript:toggleLayer('modifiedsummary');" title="Click to Expand" class="commentLink">{{modified_client_list|length}}</a> nodes were modified in the previous run.<br /></span> - <div class="items" id="modifiedsummary"><ul class="plain"> - {% for client in modified_client_list|sortname %} - {% set_interaction "foo" %} - <li><b>Node: </b></tt> - <tt><a href="{% block linkprefix3 %}#{% endblock %}{{client.name}}">{{client.name}}</a></tt><span class="mini-date">{{interaction.timestamp}}</span></li> - {% endfor %} - </ul></div> - </div> - {% endif %} - {% if extra_client_list %} - <div class="extra"> - <span class="nodelisttitle"><a href="javascript:toggleLayer('extrasummary');" title="Click to Expand" class="commentLink">{{extra_client_list|length}}</a> nodes have extra configuration. (includes both good and bad nodes)<br /></span> - <div class="items" id="extrasummary"><ul class="plain"> - {% for client in extra_client_list|sortname %} - {% set_interaction "foo" %} - <li><b>Node: </b></tt> - <tt><a href="{% block linkprefix4 %}#{% endblock %}{{client.name}}">{{client.name}}</a></tt><span class="mini-date">{{interaction.timestamp}}</span></li> - {% endfor %} - </ul></div> - </div> - {% endif %} - {% if stale_up_client_list %} - <div class="warning"> - <span class="nodelisttitle"><a href="javascript:toggleLayer('vstalesummary');" title="Click to Expand" class="commentLink">{{stale_up_client_list|length}}</a> nodes did not run within the last 24 hours but were pingable.<br /></span> - <div class="items" id="vstalesummary"><ul class="plain"> - {% for client in stale_up_client_list|sortname %} - {% set_interaction "foo" %} - <li><b>Node: </b></tt> - <tt><a href="{% block linkprefix5 %}#{% endblock %}{{client.name}}">{{client.name}}</a></tt><span class="mini-date">{{interaction.timestamp}}</span></li> - {% endfor %} - </ul></div> - </div> - {% endif %} - {% if stale_all_client_list %} - <div class="all-warning"> - <span class="nodelisttitle"><a href="javascript:toggleLayer('stalesummary');" title="Click to Expand" class="commentLink">{{stale_all_client_list|length}}</a> nodes did not run within the last 24 hours. (includes nodes up and down)<br /></span> - <div class="items" id="stalesummary"><ul class="plain"> - {% for client in stale_all_client_list|sortname %} - {% set_interaction "foo" %} - <li><b>Node: </b></tt> - <tt><a href="{% block linkprefix6 %}#{% endblock %}{{client.name}}">{{client.name}}</a></tt><span class="mini-date">{{interaction.timestamp}}</span></li> - {% endfor %} - </ul></div> - </div> - {% endif %} - {% if down_client_list %} - <div class="down"> - <span class="nodelisttitle"><a href="javascript:toggleLayer('unpingablesummary');" title="Click to Expand" class="commentLink">{{down_client_list|length}}</a> nodes were down.<br /></span> - <div class="items" id="unpingablesummary"><ul class="plain"> - {% for client in down_client_list|sortname %} - {% set_interaction "foo" %} - <li><b>Node: </b></tt> - <tt><a href="#{{client.name}}">{{client.name}}</a></tt><span class="mini-date">{{interaction.timestamp}}</span></li> - {% endfor %} - </ul></div> - </div> - {% endif %} - </div>
\ No newline at end of file diff --git a/reports/brpt/reports/templates/displays/summary.html b/reports/brpt/reports/templates/displays/summary.html deleted file mode 100644 index cf253c25c..000000000 --- a/reports/brpt/reports/templates/displays/summary.html +++ /dev/null @@ -1,29 +0,0 @@ -{% extends "base.html" %} -{% block extra_header_info %} -<script type="text/javascript" src="/site_media/CalendarPopup.js"></script> -<script language="JavaScript">var cal = new CalendarPopup();</script> -{% endblock%} -{% block title %}Display Index Listing{% endblock %} -{% block pagebanner %} - <div class="header"> - <h1>BCFG Clients Summary</h1> - <span class="notebox">Report Run @ {% now "F j, Y P"%}</span> - </div> - <br/> -{% endblock %} - -{% block content %} -<div> -<span class="mini-date"> -<b>Enter date or use calendar popup: </b> -<form name="timestamp-select"> -<input type="text" name="date1" value="{{timestamp_date}}" size=10>@ -<input type="text" name="time" value="{{timestamp_time}}" size=8> -<a href="" onClick="cal.select(document.forms['timestamp-select'].date1,'anchor1','yyyy-MM-dd'); return false;" - name="anchor1" ID="anchor1">Calendar</A> -<input type="button" name="go" value="Go" onClick="location.href='/displays/summary/'+document.forms['timestamp-select'].date1.value+'@'+document.forms['timestamp-select'].time.value;" /> - | <input type="button" name="now" value="Now" onClick="location.href='/displays/summary/';"/> -</form> -</span><br/><br/><br/></div> - {% include "displays/summary-block-direct-links.html" %} -{% endblock %} diff --git a/reports/brpt/reports/templates/displays/sys_view.html b/reports/brpt/reports/templates/displays/sys_view.html deleted file mode 100644 index 1298059bf..000000000 --- a/reports/brpt/reports/templates/displays/sys_view.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "base.html" %} -{% load django_templating_sigh %} - -{% block title %}System-View Display{% endblock %} -{% block pagebanner %} - <div class="header"> - <h1>Grand System View</h1> - <span class="notebox">Report Run @ {% now "F j, Y P"%}</span> - </div> - <br/> -{% endblock %} -{% block content %} -<center><h2>This view is deprecated and will be removed soon.</h2><br/>Please use the "Summary" view and drill down instead.</center> - - {% include "displays/summary-block.html" %} - {% for client in client_list %} - {% set_interaction "foo" %} - {% include "clients/client-nodebox.html" %} - {% endfor %} -{% endblock %} diff --git a/reports/brpt/reports/templates/displays/timing.html b/reports/brpt/reports/templates/displays/timing.html deleted file mode 100644 index e9020b8ef..000000000 --- a/reports/brpt/reports/templates/displays/timing.html +++ /dev/null @@ -1,52 +0,0 @@ -{% extends "base.html" %} - -{% block extra_header_info %} -<script type="text/javascript" src="/site_media/sorttable.js"></script> -<script type="text/javascript" src="/site_media/CalendarPopup.js"></script> -<script language="JavaScript">var cal = new CalendarPopup();</script> -{% endblock%} -{% block title %}Display Index Listing{% endblock %} - -{% block content %} - <div class="header"> - <h1>BCFG Performance Timings</h1> - <span class="notebox">Report Run @ {% now "F j, Y P"%}</span> - </div> - <br/> -<div> -<span class="mini-date"> -<b>Enter date or use calendar popup: </b> -<form name="timestamp-select"> -<input type="text" name="date1" value="{{timestamp_date}}" size=10>@ -<input type="text" name="time" value="{{timestamp_time}}" size=8> -<a href="" onClick="cal.select(document.forms['timestamp-select'].date1,'anchor1','yyyy-MM-dd'); return false;" - name="anchor1" ID="anchor1">Calendar</A> -<input type="button" name="go" value="Go" onClick="location.href='/displays/timing/'+document.forms['timestamp-select'].date1.value+'@'+document.forms['timestamp-select'].time.value;" /> - | <input type="button" name="now" value="Now" onClick="location.href='/displays/timing/';"/> -</form> -</span><br/><br/><br/></div> - <center> - <table id="t1" class="sortable"> - <tr> - <th class="sortable">Hostname</th> - <th class="sortable">Parse</th> - <th class="sortable">Probe</th> - <th class="sortable">Inventory</th> - <th class="sortable">Install</th> - <th class="sortable">Config</th> - <th class="sortable">Total</th> - </tr> - {% for dict_unit in stats_list %} - <tr> - <td class="sortable"><a href="/clients/{{dict_unit.name}}/">{{dict_unit.name}}</a></td> - <td class="sortable">{{dict_unit.parse}}</td> - <td class="sortable">{{dict_unit.probe}}</td> - <td class="sortable">{{dict_unit.inventory}}</td> - <td class="sortable">{{dict_unit.install}}</td> - <td class="sortable">{{dict_unit.config}}</td> - <td class="sortable">{{dict_unit.total}}</td> - </tr> - {% endfor %} - </table> - </center> -{% endblock %}
\ No newline at end of file diff --git a/reports/brpt/reports/templates/index.html b/reports/brpt/reports/templates/index.html deleted file mode 100644 index 002a3f770..000000000 --- a/reports/brpt/reports/templates/index.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "base.html" %} - -{% block pagebanner %} - <div class="header"> - <h1>BCFG Reports</h1> - {% comment %} <span class="notebox">Report Run @ {% now "F j, Y P"%}</span>{% endcomment %} - </div> - <br/> -{% endblock %} -{% block content %} -<h1>Welcome to the Bcfg2 Reporting System</h1> -<p> -Please use the links at the left to navigate. -</p> -{% endblock %} diff --git a/reports/brpt/reports/templatetags/__init__.py b/reports/brpt/reports/templatetags/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/reports/brpt/reports/templatetags/__init__.py +++ /dev/null diff --git a/reports/brpt/reports/templatetags/django_templating_sigh.py b/reports/brpt/reports/templatetags/django_templating_sigh.py deleted file mode 100644 index 85f4d61a2..000000000 --- a/reports/brpt/reports/templatetags/django_templating_sigh.py +++ /dev/null @@ -1,40 +0,0 @@ -from django import template -#from brpt.reports.models import Client, Interaction, Bad, Modified, Extra - -register = template.Library() - -def set_interaction(parser, token): - try: - # Splitting by None == splitting by spaces. - tag_name, format_string = token.contents.split(None, 1) - except ValueError: - raise template.TemplateSyntaxError, "%r tag requires an argument" % token.contents[0] - if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")): - raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name - return SetInteraction(format_string[1:-1]) - -def sortwell(value): - "sorts a list(or evaluates queryset to list) of bad, extra, or modified items in the best way for presentation" - configItems = list(value) - configItems.sort(lambda x,y: cmp(x.name, y.name)) - configItems.sort(lambda x,y: cmp(x.kind, y.kind)) - return configItems -def sortname(value): - "sorts a list( or evaluates queryset) by name" - configItems = list(value) - configItems.sort(lambda x,y: cmp(x.name, y.name)) - return configItems - -class SetInteraction(template.Node): - def __init__(self, times): - self.times = times#do soemthing to select different interaction with host? - def render(self, context): - try: - context['interaction'] = context['client_interaction_dict'][context['client'].id] - except:#I don't fully know what the implications of this are. - pass - return '' - -register.tag('set_interaction', set_interaction) -register.filter('sortwell', sortwell) -register.filter('sortname', sortname) diff --git a/reports/brpt/reports/views.py b/reports/brpt/reports/views.py deleted file mode 100644 index 44c858a82..000000000 --- a/reports/brpt/reports/views.py +++ /dev/null @@ -1,255 +0,0 @@ -# Create your views here. -#from django.shortcuts import get_object_or_404, render_to_response -from django.template import Context, loader -from django.http import HttpResponseRedirect, HttpResponse -from django.shortcuts import render_to_response, get_object_or_404 -from brpt.reports.models import Client, Interaction, Bad, Modified, Extra, Performance, Reason -from datetime import datetime, timedelta -from time import strptime -from django.db import connection -from django.db.backends import util -from django.contrib.auth.decorators import login_required - -def index(request): - return render_to_response('index.html') - -def config_item_modified(request, eyedee =None, timestamp = 'now'): - #if eyedee = None, dump with a 404 - timestamp = timestamp.replace("@"," ") - mod_or_bad = "modified" - - item = Modified.objects.get(id=eyedee) - #if everything is blank except current_exists, do something special - cursor = connection.cursor() - if timestamp == 'now': - cursor.execute("select client_id from reports_interaction, reports_modified_interactions, reports_client "+ - "WHERE reports_client.current_interaction_id = reports_modified_interactions.interaction_id "+ - "AND reports_modified_interactions.interaction_id = reports_interaction.id "+ - "AND reports_modified_interactions.modified_id = %s", [eyedee]) - associated_client_list = Client.objects.filter(id__in=[x[0] for x in cursor.fetchall()]) - else: - interact_queryset = Interaction.objects.interaction_per_client(timestamp) - interactionlist = [] - [interactionlist.append(x.id) for x in interact_queryset] - if not interactionlist == []: - cursor.execute("select client_id from reports_interaction, reports_modified_interactions, reports_client "+ - "WHERE reports_modified_interactions.interaction_id IN %s "+ - "AND reports_modified_interactions.interaction_id = reports_interaction.id "+ - "AND reports_modified_interactions.modified_id = %s", [interactionlist, eyedee]) - associated_client_list = Client.objects.filter(id__in=[x[0] for x in cursor.fetchall()]) - else: - associated_client_list = [] - - if timestamp == 'now': - timestamp = datetime.now().isoformat('@') - - return render_to_response('config_items/index.html', {'item':item, - 'mod_or_bad':mod_or_bad, - 'associated_client_list':associated_client_list, - 'timestamp' : timestamp, - 'timestamp_date' : timestamp[:10], - 'timestamp_time' : timestamp[11:19]}) - - -def config_item_bad(request, eyedee = None, timestamp = 'now'): - timestamp = timestamp.replace("@"," ") - mod_or_bad = "bad" - item = Bad.objects.get(id=eyedee) - cursor = connection.cursor() - if timestamp == 'now': - cursor.execute("select client_id from reports_interaction, reports_bad_interactions, reports_client "+ - "WHERE reports_client.current_interaction_id = reports_bad_interactions.interaction_id "+ - "AND reports_bad_interactions.interaction_id = reports_interaction.id "+ - "AND reports_bad_interactions.bad_id = %s", [eyedee]) - associated_client_list = Client.objects.filter(id__in=[x[0] for x in cursor.fetchall()]) - else: - interact_queryset = Interaction.objects.interaction_per_client(timestamp) - interactionlist = [] - [interactionlist.append(x.id) for x in interact_queryset] - if not interactionlist == []: - cursor.execute("SELECT DISTINCT client_id from reports_interaction, reports_bad_interactions, reports_client "+ - "WHERE reports_bad_interactions.interaction_id IN %s "+ - "AND reports_bad_interactions.interaction_id = reports_interaction.id "+ - "AND reports_bad_interactions.bad_id = %s", [interactionlist, eyedee]) - associated_client_list = Client.objects.filter(id__in=[x[0] for x in cursor.fetchall()]) - else: - associated_client_list = None - - if timestamp == 'now': - timestamp = datetime.now().isoformat('@') - - return render_to_response('config_items/index.html', {'item':item, - 'mod_or_bad':mod_or_bad, - 'associated_client_list':associated_client_list, - 'timestamp' : timestamp, - 'timestamp_date' : timestamp[:10], - 'timestamp_time' : timestamp[11:19]}) - - - -def client_index(request): - client_list = Client.objects.all().order_by('name') - client_list_a = client_list[:len(client_list)/2] - client_list_b = client_list[len(client_list)/2:] - return render_to_response('clients/index.html', {'client_list_a': client_list_a, - 'client_list_b': client_list_b}) - -def client_detail(request, hostname = None, pk = None): - #SETUP error pages for when you specify a client or interaction that doesn't exist - client = get_object_or_404(Client, name=hostname) - if(pk == None): - interaction = client.current_interaction - else: - interaction = client.interactions.get(pk=pk)#can this be a get object or 404? - return render_to_response('clients/detail.html', {'client': client, 'interaction': interaction}) - -def display_sys_view(request, timestamp = 'now'): - client_lists = prepare_client_lists(request, timestamp) - return render_to_response('displays/sys_view.html', client_lists) - -def display_summary(request, timestamp = 'now'): - - client_lists = prepare_client_lists(request, timestamp) - #this returns timestamp and the timestamp parts too - return render_to_response('displays/summary.html', client_lists) - -def display_timing(request, timestamp = 'now'): - #We're going to send a list of dictionaries. Each dictionary will be a row in the table - #+------+-------+----------------+-----------+---------+----------------+-------+ - #| name | parse | probe download | inventory | install | cfg dl & parse | total | - #+------+-------+----------------+-----------+---------+----------------+-------+ - client_list = Client.objects.all().order_by('name') - stats_list = [] - - if not timestamp == 'now': - results = Performance.objects.performance_per_client(timestamp.replace("@"," ")) - else: - results = Performance.objects.performance_per_client() - timestamp = datetime.now().isoformat('@') - - for client in client_list:#Go explicitly to an interaction ID! (new item in dictionary) - try: - d = results[client.name] - except KeyError: - d = {} - - dict_unit = {} - try: - dict_unit["name"] = client.name #node name - except: - dict_unit["name"] = "n/a" - try: - dict_unit["parse"] = round(d["config_parse"] - d["config_download"], 4) #parse - except: - dict_unit["parse"] = "n/a" - try: - dict_unit["probe"] = round(d["probe_upload"] - d["start"], 4) #probe - except: - dict_unit["probe"] = "n/a" - try: - dict_unit["inventory"] = round(d["inventory"] - d["initialization"], 4) #inventory - except: - dict_unit["inventory"] = "n/a" - try: - dict_unit["install"] = round(d["install"] - d["inventory"], 4) #install - except: - dict_unit["install"] = "n/a" - try: - dict_unit["config"] = round(d["config_parse"] - d["probe_upload"], 4)#config download & parse - except: - dict_unit["config"] = "n/a" - try: - dict_unit["total"] = round(d["finished"] - d["start"], 4) #total - except: - dict_unit["total"] = "n/a" - - stats_list.append(dict_unit) - - return render_to_response('displays/timing.html', {'client_list': client_list, - 'stats_list': stats_list, - 'timestamp' : timestamp, - 'timestamp_date' : timestamp[:10], - 'timestamp_time' : timestamp[11:19]}) - -def display_index(request): - return render_to_response('displays/index.html') - -def prepare_client_lists(request, timestamp = 'now'): - timestamp = timestamp.replace("@"," ") - #client_list = Client.objects.all().order_by('name')#change this to order by interaction's state - client_interaction_dict = {} - clean_client_list = [] - bad_client_list = [] - extra_client_list = [] - modified_client_list = [] - stale_up_client_list = [] - #stale_all_client_list = [] - down_client_list = [] - - cursor = connection.cursor() - - interact_queryset = Interaction.objects.interaction_per_client(timestamp) - # or you can specify a time like this: '2007-01-01 00:00:00' - [client_interaction_dict.__setitem__(x.client_id,x) for x in interact_queryset] - client_list = Client.objects.filter(id__in=client_interaction_dict.keys()).order_by('name') - - [clean_client_list.append(x) for x in Client.objects.filter(id__in=[y.client_id for y in interact_queryset.filter(state='clean')])] - [bad_client_list.append(x) for x in Client.objects.filter(id__in=[y.client_id for y in interact_queryset.filter(state='dirty')])] - - client_ping_dict = {} - [client_ping_dict.__setitem__(x,'Y') for x in client_interaction_dict.keys()]#unless we know otherwise... - - try: - cursor.execute("select reports_ping.status, x.client_id from (select client_id, MAX(endtime) "+ - "as timer from reports_ping GROUP BY client_id) x, reports_ping where "+ - "reports_ping.client_id = x.client_id AND reports_ping.endtime = x.timer") - [client_ping_dict.__setitem__(x[1],x[0]) for x in cursor.fetchall()] - except: - pass #This is to fix problems when you have only zero records returned - - client_down_ids = [y for y in client_ping_dict.keys() if client_ping_dict[y]=='N'] - if not client_down_ids == []: - [down_client_list.append(x) for x in Client.objects.filter(id__in=client_down_ids)] - - if (timestamp == 'now' or timestamp == None): - cursor.execute("select client_id, MAX(timestamp) as timestamp from reports_interaction GROUP BY client_id") - results = cursor.fetchall() - for x in results: - if type(x[1]) == type(""): - x[1] = util.typecast_timestamp(x[1]) - stale_all_client_list = Client.objects.filter(id__in=[x[0] for x in results if datetime.now() - x[1] > timedelta(days=1)]) - else: - cursor.execute("select client_id, timestamp, MAX(timestamp) as timestamp from reports_interaction "+ - "WHERE timestamp < %s GROUP BY client_id", [timestamp]) - t = strptime(timestamp,"%Y-%m-%d %H:%M:%S") - datetimestamp = datetime(t[0], t[1], t[2], t[3], t[4], t[5]) - results = cursor.fetchall() - for x in results: - if type(x[1]) == type(""): - x[1] = util.typecast_timestamp(x[1]) - stale_all_client_list = Client.objects.filter(id__in=[x[0] for x in results if datetimestamp - x[1] > timedelta(days=1)]) - - [stale_up_client_list.append(x) for x in stale_all_client_list if not client_ping_dict[x.id]=='N'] - - - cursor.execute("SELECT reports_client.id FROM reports_client, reports_interaction, reports_modified_interactions WHERE reports_client.id=reports_interaction.client_id AND reports_interaction.id = reports_modified_interactions.interaction_id GROUP BY reports_client.id") - modified_client_list = Client.objects.filter(id__in=[x[0] for x in cursor.fetchall()]) - - cursor.execute("SELECT reports_client.id FROM reports_client, reports_interaction, reports_extra_interactions WHERE reports_client.id=reports_interaction.client_id AND reports_interaction.id = reports_extra_interactions.interaction_id GROUP BY reports_client.id") - extra_client_list = Client.objects.filter(id__in=[x[0] for x in cursor.fetchall()]) - - if timestamp == 'now': - timestamp = datetime.now().isoformat('@') - - return {'client_list': client_list, - 'client_interaction_dict':client_interaction_dict, - 'clean_client_list': clean_client_list, - 'bad_client_list': bad_client_list, - 'extra_client_list': extra_client_list, - 'modified_client_list': modified_client_list, - 'stale_up_client_list': stale_up_client_list, - 'stale_all_client_list': stale_all_client_list, - 'down_client_list': down_client_list, - 'timestamp' : timestamp, - 'timestamp_date' : timestamp[:10], - 'timestamp_time' : timestamp[11:19]} diff --git a/reports/brpt/settings.py b/reports/brpt/settings.py deleted file mode 100644 index 6f490d688..000000000 --- a/reports/brpt/settings.py +++ /dev/null @@ -1,92 +0,0 @@ -# Django settings for brpt project. -from ConfigParser import ConfigParser, NoSectionError, NoOptionError -c = ConfigParser() -c.read(['/etc/bcfg2.conf'])#This needs to be configurable one day somehow -sqlitedbpath = "%s/etc/brpt.sqlite" % c.get('server', 'repository') - -DEBUG = True -TEMPLATE_DEBUG = DEBUG - -ADMINS = ( - ('Joey Hagedorn', 'hagedorn@mcs.anl.gov'), -) - -MANAGERS = ADMINS - -DATABASE_ENGINE = 'sqlite3' # 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'. -DATABASE_NAME = sqlitedbpath # Or path to database file if using sqlite3. -DATABASE_USER = '' # Not used with sqlite3. -DATABASE_PASSWORD = '' # Not used with sqlite3. -DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3. -DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3. - -# Local time zone for this installation. All choices can be found here: -# http://www.postgresql.org/docs/current/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE -TIME_ZONE = 'America/Chicago' - -# Language code for this installation. All choices can be found here: -# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes -# http://blogs.law.harvard.edu/tech/stories/storyReader$15 -LANGUAGE_CODE = 'en-us' - -SITE_ID = 1 - -# Absolute path to the directory that holds media. -# Example: "/home/media/media.lawrence.com/" -MEDIA_ROOT = '' - -# URL that handles the media served from MEDIA_ROOT. -# Example: "http://media.lawrence.com" -MEDIA_URL = '' - -# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a -# trailing slash. -# Examples: "http://foo.com/media/", "/media/". -ADMIN_MEDIA_PREFIX = '/media/' - -# Make this unique, and don't share it with anybody. -SECRET_KEY = 'eb5+y%oy-qx*2+62vv=gtnnxg1yig_odu0se5$h0hh#pc*lmo7' - -# List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.load_template_source', - 'django.template.loaders.app_directories.load_template_source', -# 'django.template.loaders.eggs.load_template_source', -) - -MIDDLEWARE_CLASSES = ( - 'django.middleware.common.CommonMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.middleware.doc.XViewMiddleware', -) - -ROOT_URLCONF = 'brpt.urls' - -# Authentication Settings -# Use NIS authentication backend defined in backends.py -AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend', - 'brpt.backends.NISBackend') -# The NIS group authorized to login to BCFG2's reportinvg system -AUTHORIZED_GROUP = '' -#create login url area: -import django.contrib.auth -django.contrib.auth.LOGIN_URL = '/login' - -SESSION_EXPIRE_AT_BROWSER_CLOSE = True - - - -TEMPLATE_DIRS = ( - # Put strings here, like "/home/html/django_templates". - # Always use forward slashes, even on Windows. -) - -INSTALLED_APPS = ( - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.sites', - 'django.contrib.admin', - 'brpt.reports' -) diff --git a/reports/brpt/urls.py b/reports/brpt/urls.py deleted file mode 100644 index d6f9ecb3a..000000000 --- a/reports/brpt/urls.py +++ /dev/null @@ -1,36 +0,0 @@ -from django.conf.urls.defaults import * - -urlpatterns = patterns('', - # Example: - # (r'^brpt/', include('brpt.apps.foo.urls.foo')), - (r'^/*$','brpt.reports.views.index'), - (r'^clients/(?P<hostname>\S+)/(?P<pk>\d+)/$', 'brpt.reports.views.client_detail'), - (r'^clients/(?P<hostname>\S+)/$', 'brpt.reports.views.client_detail'), - (r'^clients/(?P<hostname>\S+)$', 'brpt.reports.views.client_detail'), - #hack because hostnames have periods and we still want to append slash - (r'^clients/$','brpt.reports.views.client_index'), - (r'^displays/sys-view/(?P<timestamp>(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01][0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$','brpt.reports.views.display_sys_view'), - (r'^displays/sys-view/$','brpt.reports.views.display_sys_view'), - (r'^displays/summary/(?P<timestamp>(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01][0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$','brpt.reports.views.display_summary'), - (r'^displays/summary/$','brpt.reports.views.display_summary'), - (r'^displays/timing/(?P<timestamp>(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01][0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$','brpt.reports.views.display_timing'), - (r'^displays/timing/$','brpt.reports.views.display_timing'), - (r'^displays/$','brpt.reports.views.display_index'), - - (r'^elements/modified/(?P<eyedee>\d+)/(?P<timestamp>(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01][0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$','brpt.reports.views.config_item_modified'), - (r'^elements/modified/(?P<eyedee>\d+)/$','brpt.reports.views.config_item_modified'), - (r'^elements/bad/(?P<eyedee>\d+)/(?P<timestamp>(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])@([01][0-9]|2[0-3]):([0-5][0-9]|60):([0-5][0-9]|60))/$','brpt.reports.views.config_item_bad'), - (r'^elements/bad/(?P<eyedee>\d+)/$','brpt.reports.views.config_item_bad'), - ) - - # Uncomment this for admin: - #(r'^admin/', include('django.contrib.admin.urls')), - - -## Uncomment this section if using authentication -#urlpatterns += patterns('', -# (r'^login/$', 'django.contrib.auth.views.login', -# {'template_name': 'auth/login.html'}), -# (r'^logout/$', 'django.contrib.auth.views.logout', -# {'template_name': 'auth/logout.html'}) -# ) diff --git a/reports/site_media/boxypastel.css b/reports/site_media/boxypastel.css index 896c8c428..f4e34eea4 100644 --- a/reports/site_media/boxypastel.css +++ b/reports/site_media/boxypastel.css @@ -149,6 +149,29 @@ span.mini-date { right: 65px; } + +div.dirty-lineitem { + background: #FF6A6A; + width:100%; + } +div.modified-lineitem { + background: #FFEC8B; + } +div.clean-lineitem { + background: #9AFF9A; + width:100%; + } +div.extra-lineitem { + background: #6699CC; + } +div.warning-lineitem { + background: #FF9933; + } + + + + + h2 { font-size: 16px; color: #000; diff --git a/reports/site_media/global.css b/reports/site_media/global.css index 1dc57f3ca..cbc28fcd3 100644 --- a/reports/site_media/global.css +++ b/reports/site_media/global.css @@ -4,6 +4,6 @@ body { padding:0; font-size:12px; font-family:"Lucida Grande","Bitstream Vera Sans",Verdana,Arial,sans-serif; - color:#000; - background:#fff; + color:#fff; + background:#000; } |