summaryrefslogtreecommitdiffstats
path: root/src/lib/Server/Reports/reports
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/Server/Reports/reports')
-rw-r--r--src/lib/Server/Reports/reports/models.py78
-rw-r--r--src/lib/Server/Reports/reports/templates/clients/client-nodebox.html26
-rw-r--r--src/lib/Server/Reports/reports/templates/config_items/listing.html4
-rw-r--r--src/lib/Server/Reports/reports/templatetags/django_templating_sigh.py4
-rw-r--r--src/lib/Server/Reports/reports/views.py136
5 files changed, 90 insertions, 158 deletions
diff --git a/src/lib/Server/Reports/reports/models.py b/src/lib/Server/Reports/reports/models.py
index b54d83912..333618a56 100644
--- a/src/lib/Server/Reports/reports/models.py
+++ b/src/lib/Server/Reports/reports/models.py
@@ -18,6 +18,15 @@ PING_CHOICES = (
('Up (Y)', 'Y'),
('Down (N)', 'N')
)
+TYPE_BAD = 1
+TYPE_MODIFIED = 2
+TYPE_EXTRA = 3
+
+TYPE_CHOICES = (
+ (TYPE_BAD, 'Bad'),
+ (TYPE_MODIFIED, 'Modified'),
+ (TYPE_EXTRA, 'Extra'),
+)
class ClientManager(models.Manager):
'''extended client manager functions'''
def active(self,timestamp='now'):
@@ -57,19 +66,6 @@ class Client(models.Model):
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")
@@ -116,6 +112,7 @@ class Interaction(models.Model):
client_version = models.CharField(maxlength=32)#Client Version
goodcount = models.IntegerField()#of good config-items
totalcount = models.IntegerField()#of total config-items
+ server = models.CharField(maxlength=256) # Name of the server used for the interaction
def __str__(self):
return "With " + self.client.name + " @ " + self.timestamp.isoformat()
@@ -158,7 +155,16 @@ class Interaction(models.Model):
super(Interaction, self).save() #call the real save...
self.client.current_interaction = self.client.interactions.latest()
self.client.save()#save again post update
-
+
+ def bad(self):
+ return Entries_interactions.objects.select_related().filter(interaction=self, type=TYPE_BAD)
+
+ def modified(self):
+ return Entries_interactions.objects.select_related().filter(interaction=self, type=TYPE_MODIFIED)
+
+ def extra(self):
+ return Entries_interactions.objects.select_related().filter(interaction=self, type=TYPE_EXTRA)
+
objects = InteractiveManager()
class Admin:
@@ -187,36 +193,21 @@ class Reason(models.Model):
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)
+class Entries(models.Model):
+ """ Contains all the entries feed by the client """
+ name = models.CharField(maxlength=128, core=True, db_index=True)
+ kind = models.CharField(maxlength=16, choices=KIND_CHOICES, db_index=True)
+
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()
+
+class Entries_interactions(models.Model):
+ """ Define the relation between the reason, the interaction and the entry """
+ entry = models.ForeignKey(Entries)
reason = models.ForeignKey(Reason)
- def __str__(self):
- return self.name
+ interaction = models.ForeignKey(Interaction)
+ type = models.IntegerField(choices=TYPE_CHOICES)
-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'''
@@ -260,3 +251,10 @@ class Performance(models.Model):
objects = PerformanceManager()
+class InternalDatabaseVersion(models.Model):
+ '''Object that tell us to witch version is the database'''
+ version = models.IntegerField()
+ updated = models.DateTimeField(auto_now_add=True)
+
+ def __str__(self):
+ return "version %d updated the %s" % (self.version, self.updated.isoformat())
diff --git a/src/lib/Server/Reports/reports/templates/clients/client-nodebox.html b/src/lib/Server/Reports/reports/templates/clients/client-nodebox.html
index 77621cace..88cf05345 100644
--- a/src/lib/Server/Reports/reports/templates/clients/client-nodebox.html
+++ b/src/lib/Server/Reports/reports/templates/clients/client-nodebox.html
@@ -26,33 +26,33 @@
<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 %}
+ {% endif %}
+ {% if interaction.bad %}
<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>
+ <span class="nodelisttitle"><a href="javascript:toggleLayer('{{client.name}}-bad');" title="Click to expand" class="commentLink">{{interaction.bad.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="{% url Bcfg2.Server.Reports.reports.views.config_item_bad bad.id%}">{{bad.name}}</a></tt></li>
+ {% for bad in interaction.bad|sortwell %}
+ <li><strong>{{bad.entry.kind}}: </strong><tt><a href="{% url Bcfg2.Server.Reports.reports.views.config_item_bad bad.id%}">{{bad.entry.name}}</a></tt></li>
{% endfor %}
</ul></div>
</div>
{% endif %}
- {% if interaction.modified_items.all %}
+ {% if interaction.modified %}
<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>
+ <span class="nodelisttitle"><a href="javascript:toggleLayer('{{client.name}}-modified');" title="Click to expand" class="commentLink">{{interaction.modified.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="{% url Bcfg2.Server.Reports.reports.views.config_item_modified modified.id %}">{{modified.name}}</a></tt></li>
+ {% for modified in interaction.modified|sortwell %}
+ <li><strong>{{modified.entry.kind}}: </strong><tt><a href="{% url Bcfg2.Server.Reports.reports.views.config_item_modified modified.id %}">{{modified.name}}</a></tt></li>
{% endfor %}
</ul></div>
</div>
{% endif %}
- {% if interaction.extra_items.all %}
+ {% if interaction.extra %}
<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>
+ <span class="nodelisttitle"><a href="javascript:toggleLayer('{{client.name}}-extra');" title="Click to expand" class="commentLink">{{interaction.extra.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>
+ {% for extra in interaction.extra|sortwell %}
+ <li><strong>{{extra.entry.kind}}: </strong><tt>{{extra.entry.name}}</tt></li>
{% endfor %}
</ul></div>
</div>
diff --git a/src/lib/Server/Reports/reports/templates/config_items/listing.html b/src/lib/Server/Reports/reports/templates/config_items/listing.html
index f3be1e4d5..1dba4bd6d 100644
--- a/src/lib/Server/Reports/reports/templates/config_items/listing.html
+++ b/src/lib/Server/Reports/reports/templates/config_items/listing.html
@@ -15,7 +15,7 @@ YAHOO.example.init = function( ){
{% for item_list in item_list_pseudodict %}
tabView.addTab( new YAHOO.widget.Tab({
label: '{{item_list.0}}',
- content: '<p><ul style="list-style-type:none;">{% for item in item_list.1|sortwell %}<li><strong>{{item.kind}}: </strong><tt>{% ifequal mod_or_bad "modified" %}<a href="{%url Bcfg2.Server.Reports.reports.views.config_item_modified eyedee=item.id%}">{{item.name}}</a>{% else %}<a href="{%url Bcfg2.Server.Reports.reports.views.config_item_bad eyedee=item.id%}">{{item.name}}</a>{% endifequal %}</tt></li>{% endfor %}</ul></p>',
+ content: '<p><ul style="list-style-type:none;">{% for item in item_list.1|sortwell %}<li><strong>{{item.entry.kind}}: </strong><tt>{% ifequal mod_or_bad "modified" %}<a href="{%url Bcfg2.Server.Reports.reports.views.config_item_modified eyedee=item.id%}">{{item.entry.name}}</a>{% else %}<a href="{%url Bcfg2.Server.Reports.reports.views.config_item_bad eyedee=item.id%}">{{item.entry.name}}</a>{% endifequal %}</tt></li>{% endfor %}</ul></p>',
active: 'True'
}));
{% endfor %}
@@ -48,4 +48,4 @@ YAHOO.example.init();
{% else %}
<p>There are currently no inconsistent configuration entries.</p>
{% endif %}
-{% endblock %} \ No newline at end of file
+{% endblock %}
diff --git a/src/lib/Server/Reports/reports/templatetags/django_templating_sigh.py b/src/lib/Server/Reports/reports/templatetags/django_templating_sigh.py
index 5591e065e..c0d05d2c1 100644
--- a/src/lib/Server/Reports/reports/templatetags/django_templating_sigh.py
+++ b/src/lib/Server/Reports/reports/templatetags/django_templating_sigh.py
@@ -17,8 +17,8 @@ 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))
+ configItems.sort(lambda x,y: cmp(x.entry.name, y.entry.name))
+ configItems.sort(lambda x,y: cmp(x.entry.kind, y.entry.kind))
return configItems
def sortname(value):
"sorts a list( or evaluates queryset) by name"
diff --git a/src/lib/Server/Reports/reports/views.py b/src/lib/Server/Reports/reports/views.py
index 9934a0dc3..d5367b168 100644
--- a/src/lib/Server/Reports/reports/views.py
+++ b/src/lib/Server/Reports/reports/views.py
@@ -3,7 +3,8 @@
from django.template import Context, loader
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render_to_response, get_object_or_404
-from Bcfg2.Server.Reports.reports.models import Client, Interaction, Bad, Modified, Extra, Performance, Reason
+from Bcfg2.Server.Reports.reports.models import Client, Interaction, Entries, Entries_interactions, Performance, Reason
+from Bcfg2.Server.Reports.reports.models import TYPE_BAD, TYPE_MODIFIED, TYPE_EXTRA
from datetime import datetime, timedelta
from time import strptime
from django.db import connection
@@ -14,29 +15,34 @@ from sets import Set
def index(request):
return render_to_response('index.html')
-def config_item_modified(request, eyedee =None, timestamp = 'now'):
+def config_item_modified(request, eyedee =None, timestamp = 'now', type=TYPE_MODIFIED):
#if eyedee = None, dump with a 404
timestamp = timestamp.replace("@"," ")
- mod_or_bad = "modified"
+ if type == TYPE_MODIFIED:
+ mod_or_bad = "modified"
+ else:
+ mod_or_bad = "bad"
- item = Modified.objects.get(id=eyedee)
+ item = Entries_interactions.objects.get(id=eyedee).entry
#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])
+ cursor.execute("select client_id from reports_interaction, reports_entries_interactions, reports_client "+
+ "WHERE reports_client.current_interaction_id = reports_entries_interactions.interaction_id "+
+ "AND reports_entries_interactions.interaction_id = reports_interaction.id "+
+ "AND reports_entries_interactions.entry_id = %s " +
+ "AND reports_entries_interactions.type = %s", [eyedee, type])
associated_client_list = Client.objects.active(timestamp).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])
+ cursor.execute("select client_id from reports_interaction, reports_entries_interactions, reports_client "+
+ "WHERE reports_entries_interactions.interaction_id IN %s "+
+ "AND reports_entries_interactions.interaction_id = reports_interaction.id "+
+ "AND reports_entries_interactions.modified_id = %s " +
+ "AND reports_entries_interactions.type = %s ", [interactionlist, eyedee, type])
associated_client_list = Client.objects.active(timestamp).filter(id__in=[x[0] for x in cursor.fetchall()])
else:
associated_client_list = []
@@ -50,64 +56,25 @@ def config_item_modified(request, eyedee =None, timestamp = 'now'):
'timestamp' : timestamp,
'timestamp_date' : timestamp[:10],
'timestamp_time' : timestamp[11:19]})
-
+
def config_item_bad(request, eyedee = None, timestamp = 'now'):
+ return config_item_modified(request, eyedee, timestamp, TYPE_BAD)
+
+def bad_item_index(request, timestamp = 'now', type=TYPE_BAD):
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.active(timestamp).filter(id__in=[x[0] for x in cursor.fetchall()])
+ if type == TYPE_BAD:
+ mod_or_bad = "bad"
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.active(timestamp).filter(id__in=[x[0] for x in cursor.fetchall()])
+ mod_or_bad = "modified"
+
+ current_clients = [c.current_interaction for c in Client.objects.active(timestamp)]
+ item_list_dict = {}
+ for x in Entries_interactions.objects.select_related().filter(interaction__in=current_clients, type=type).distinct():
+ if item_list_dict.get(x.entry.kind, None):
+ item_list_dict[x.entry.kind].append(x)
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 bad_item_index(request, timestamp = 'now'):
- timestamp = timestamp.replace("@"," ")
- mod_or_bad = "bad"
- cursor = connection.cursor()
-
- if timestamp == 'now':
- bad_kinds = dict([(x,x.kind) for x in Bad.objects.filter(interactions__in=
- [c.current_interaction
- for c in Client.objects.active(timestamp)]).distinct()])
- kinds = list(Set(bad_kinds.values()))
- item_list_dict = dict([(x,[]) for x in kinds])
- for obj in bad_kinds:
- item_list_dict[obj.kind].append(obj)
-
- else: #this isn't done yet
- bad_kinds = dict([(x,x.kind) for x in Bad.objects.filter(interactions__in=
- [c.current_interaction
- for c in Client.objects.active(timestamp)]).distinct()])
- kinds = list(Set(bad_kinds.values()))
- item_list_dict = dict([(x,[]) for x in kinds])
- for obj in bad_kinds:
- item_list_dict[obj.kind].append(obj)
+ item_list_dict[x.entry.kind] = [x]
item_list_pseudodict = item_list_dict.items()
if timestamp == 'now':
@@ -119,40 +86,7 @@ def bad_item_index(request, timestamp = 'now'):
'timestamp_date' : timestamp[:10],
'timestamp_time' : timestamp[11:19]})
def modified_item_index(request, timestamp = 'now'):
- timestamp = timestamp.replace("@"," ")
- mod_or_bad = "modified"
- cursor = connection.cursor()
-
- if timestamp == 'now':
- mod_kinds = dict([(x,x.kind) for x in Modified.objects.filter(interactions__in=
- [c.current_interaction
- for c in Client.objects.active(timestamp)]).distinct()])
- #this will need expiration support
- kinds = list(Set(mod_kinds.values()))
- item_list_dict = dict([(x,[]) for x in kinds])
- for obj in mod_kinds:
- item_list_dict[obj.kind].append(obj)
-
- else: #this isn't done yet
- mod_kinds = dict([(x,x.kind) for x in Modified.objects.filter(interactions__in=
- [c.current_interaction
- for c in Client.objects.active(timestamp)]).distinct()])
- #this will need expiration support
- kinds = list(Set(mod_kinds.values()))
- item_list_dict = dict([(x,[]) for x in kinds])
- for obj in mod_kinds:
- item_list_dict[obj.kind].append(obj)
-
- item_list_pseudodict = item_list_dict.items()
- if timestamp == 'now':
- timestamp = datetime.now().isoformat('@')
-
- return render_to_response('config_items/listing.html', {'item_list_pseudodict':item_list_pseudodict,
- 'mod_or_bad':mod_or_bad,
- 'timestamp' : timestamp,
- 'timestamp_date' : timestamp[:10],
- 'timestamp_time' : timestamp[11:19]})
-
+ return bad_item_index(request, timestamp, TYPE_MODIFIED)
def client_index(request, timestamp = 'now'):
timestamp = timestamp.replace("@"," ")
@@ -332,10 +266,10 @@ def prepare_client_lists(request, timestamp = 'now'):
[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")
+ cursor.execute("SELECT reports_client.id FROM reports_client, reports_interaction, reports_entries_interactions WHERE reports_client.id=reports_interaction.client_id AND reports_interaction.id = reports_entries_interactions.interaction_id and reports_entries_interactions.type=%s GROUP BY reports_client.id", [TYPE_MODIFIED])
modified_client_list = Client.objects.active(timestamp).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")
+ cursor.execute("SELECT reports_client.id FROM reports_client, reports_interaction, reports_entries_interactions WHERE reports_client.id=reports_interaction.client_id AND reports_interaction.id = reports_entries_interactions.interaction_id and reports_entries_interactions.type=%s GROUP BY reports_client.id", [TYPE_EXTRA])
extra_client_list = Client.objects.active(timestamp).filter(id__in=[x[0] for x in cursor.fetchall()])
if timestamp == 'now':