diff options
Diffstat (limited to 'src/lib/Bcfg2/Server/Reports/reports/models.py')
-rw-r--r-- | src/lib/Bcfg2/Server/Reports/reports/models.py | 139 |
1 files changed, 96 insertions, 43 deletions
diff --git a/src/lib/Bcfg2/Server/Reports/reports/models.py b/src/lib/Bcfg2/Server/Reports/reports/models.py index 35f2a4393..4b078eb2c 100644 --- a/src/lib/Bcfg2/Server/Reports/reports/models.py +++ b/src/lib/Bcfg2/Server/Reports/reports/models.py @@ -23,16 +23,13 @@ KIND_CHOICES = ( ('Path', 'symlink'), ('Service', 'Service'), ) -PING_CHOICES = ( - #These are possible ping states - ('Up (Y)', 'Y'), - ('Down (N)', 'N') -) +TYPE_GOOD = 0 TYPE_BAD = 1 TYPE_MODIFIED = 2 TYPE_EXTRA = 3 TYPE_CHOICES = ( + (TYPE_GOOD, 'Good'), (TYPE_BAD, 'Bad'), (TYPE_MODIFIED, 'Modified'), (TYPE_EXTRA, 'Extra'), @@ -87,30 +84,9 @@ class Client(models.Model): pass -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(max_length=4, choices=PING_CHOICES) # up/down - - class Meta: - get_latest_by = 'endtime' - - class InteractiveManager(models.Manager): """Manages interactions objects.""" - def recent_interactions_dict(self, maxdate=None, active_only=True): - """ - Return the most recent interactions for clients as of a date. - - This method uses aggregated queries to return a ValuesQueryDict object. - Faster then raw sql since this is executed as a single query. - """ - - return list(self.values('client').annotate(max_timestamp=Max('timestamp')).values()) - def interaction_per_client(self, maxdate=None, active_only=True): """ Returns the most recent interactions for clients as of a date @@ -154,15 +130,15 @@ class InteractiveManager(models.Manager): cursor.execute(sql) return [item[0] for item in cursor.fetchall()] except: - '''FIXME - really need some error hadling''' + '''FIXME - really need some error handling''' pass return [] class Interaction(models.Model): """Models each reconfiguration operation interaction between client and server.""" - client = models.ForeignKey(Client, related_name="interactions",) - timestamp = models.DateTimeField() # Timestamp for this record + client = models.ForeignKey(Client, related_name="interactions") + timestamp = models.DateTimeField(db_index=True) # Timestamp for this record state = models.CharField(max_length=32) # good/bad/modified/etc repo_rev_code = models.CharField(max_length=64) # repo revision at time of interaction goodcount = models.IntegerField() # of good config-items @@ -270,27 +246,47 @@ class Interaction(models.Model): class Reason(models.Model): """reason why modified or bad entry did not verify, or changed.""" - owner = models.TextField(max_length=128, blank=True) - current_owner = models.TextField(max_length=128, blank=True) - group = models.TextField(max_length=128, blank=True) - current_group = models.TextField(max_length=128, blank=True) - perms = models.TextField(max_length=4, blank=True) # txt fixes typing issue - current_perms = models.TextField(max_length=4, blank=True) - status = models.TextField(max_length=3, blank=True) # on/off/(None) - current_status = models.TextField(max_length=1, blank=True) # on/off/(None) - to = models.TextField(max_length=256, blank=True) - current_to = models.TextField(max_length=256, blank=True) - version = models.TextField(max_length=128, blank=True) - current_version = models.TextField(max_length=128, blank=True) + owner = models.CharField(max_length=255, blank=True) + current_owner = models.CharField(max_length=255, blank=True) + group = models.CharField(max_length=255, blank=True) + current_group = models.CharField(max_length=255, blank=True) + perms = models.CharField(max_length=4, blank=True) + current_perms = models.CharField(max_length=4, blank=True) + status = models.CharField(max_length=128, blank=True) + current_status = models.CharField(max_length=128, blank=True) + to = models.CharField(max_length=1024, blank=True) + current_to = models.CharField(max_length=1024, blank=True) + version = models.CharField(max_length=1024, blank=True) + current_version = models.CharField(max_length=1024, blank=True) current_exists = models.BooleanField() # False means its missing. Default True - current_diff = models.TextField(max_length=1280, blank=True) + current_diff = models.TextField(max_length=1024*1024, blank=True) is_binary = models.BooleanField(default=False) is_sensitive = models.BooleanField(default=False) - unpruned = models.TextField(max_length=1280, blank=True) + unpruned = models.TextField(max_length=4096, blank=True, default='') def _str_(self): return "Reason" + def short_list(self): + rv = [] + if self.current_owner or self.current_group or self.current_perms: + rv.append("File permissions") + if self.current_status: + rv.append("Incorrect status") + if self.current_to: + rv.append("Incorrect target") + if self.current_version or self.version == 'auto': + rv.append("Wrong version") + if not self.current_exists: + rv.append("Missing") + if self.current_diff or self.is_sensitive: + rv.append("Incorrect data") + if self.unpruned: + rv.append("Directory has extra files") + if len(rv) == 0: + rv.append("Exists") + return rv + @staticmethod @transaction.commit_on_success def prune_orphans(): @@ -316,6 +312,9 @@ class Entries(models.Model): cursor.execute('delete from reports_entries where not exists (select rei.id from reports_entries_interactions rei where rei.entry_id = reports_entries.id)') transaction.set_dirty() + class Meta: + unique_together = ("name", "kind") + class Entries_interactions(models.Model): """Define the relation between the reason, the interaction and the entry.""" @@ -350,3 +349,57 @@ class InternalDatabaseVersion(models.Model): def __str__(self): return "version %d updated the %s" % (self.version, self.updated.isoformat()) + + class Meta: + get_latest_by = "version" + + +class Group(models.Model): + """ + Groups extracted from interactions + + name - The group name + + TODO - Most of this is for future use + TODO - set a default group + """ + + name = models.CharField(max_length=255, unique=True) + profile = models.BooleanField(default=False) + public = models.BooleanField(default=False) + category = models.CharField(max_length=1024, blank=True) + comment = models.TextField(blank=True) + + groups = models.ManyToManyField("self", symmetrical=False) + bundles = models.ManyToManyField("Bundle") + + def __unicode__(self): + return self.name + + +class Bundle(models.Model): + """ + Bundles extracted from interactions + + name - The bundle name + """ + + name = models.CharField(max_length=255, unique=True) + + def __unicode__(self): + return self.name + + +class InteractionMetadata(models.Model): + """ + InteractionMetadata + + Hold extra data associated with the client and interaction + """ + + interaction = models.OneToOneField(Interaction, primary_key=True, related_name='metadata') + profile = models.ForeignKey(Group, related_name="+") + groups = models.ManyToManyField(Group) + bundles = models.ManyToManyField(Bundle) + + |