Michael DeHaan wrote:
Adam Rosenwald wrote:
  
As per discussion on IRC #cobbler today.  I noticed that individual item 
(as opposed to collections of 'systems', 'profiles', etc.) reporting is 
broken.  The patch (below) creates two additional functions for 
item-based reporting: one printing 'all fields' and one printing 'some 
fields'.  The program logic has been adjusted and the original 
(collection) function names have been modified.

FYI,

 - A.
  
    

I remember talking with you, but you can you explain "broken" ?

I think you mean

"cobbler system report --name=foo"  # not broken

"cobbler report --what=systems --name=foo"  # possibly doesn't work?  
(explain?)

Can you share sample output and commands with what you've added.
  
Bug #1: "cobbler report --format=<non-text> --name=foo" returns output for all collections rather for a single item (i.e. all systems + all profiles + ...)
Bug #2: "cobbler report --what=<collection> --format=<non-text> --fields=field1,field1,...,fieldN" returns a stack trace if an interface is defined in the entity.

These bugs, along with an additional feature enhancement, are fixed in the message with subject "[PATCH] Cobbler Reporting Fixes" (earlier in this thread).

The feature enhancement permits one to report on 'inner variables', like ks_meta{var1}.

Example: "cobbler report --name=foo --format=<non-text> --fields=w,x,y[z]" outputs a report for foo with headers ["w", "x", "z"] and the respective values for w, x, and y[z] in the body.

---

One more thing, I understand why reports with text formatting querying subfields are not currently permitted: the item{_X}.printable() function does not take arguments; hence it will always print all fields.  It may be worthwhile to modify them (i.e. the printable() functions) or write another set of printable() functions which accepts arguments.  Then one can get a report with text formatting querying subfields.  I don't know whether this is worthwhile, since one can always pipe output and manipulate it; however, for the sake of elegance, the matrix of reporting features will all be functional.

Regards,

 - Adam.
I agree the "cobbler report" command (the variant of cobbler noun 
report) that offers additional reporting options needs some work.

Thanks!

--Michael

  
---

 From 999a6b1b87206f68bf127f5479b74c4279a370f7 Mon Sep 17 00:00:00 2001
From: ARos <aros@linkshare.com>
Date: Sat, 28 Mar 2009 00:01:27 +0000
Subject: [PATCH] Break up reporting functions by "collection" and by "item".
 - Adam R.

---
 cobbler/action_report.py |   98 
+++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 84 insertions(+), 14 deletions(-)

diff --git a/cobbler/action_report.py b/cobbler/action_report.py
index 2288433..f24bb9f 100644
--- a/cobbler/action_report.py
+++ b/cobbler/action_report.py
@@ -213,7 +213,7 @@ class Report:
             print obj.printable()
         return True
     
-    def reporting_print_all_fields(self, collection, report_type, 
report_noheaders):
+    def reporting_print_all_fields_collection(self, collection, 
report_type, report_noheaders):
         """
         Prints all fields in a collection as a table given the report type
         """
@@ -250,7 +250,41 @@ class Report:
         
         return True
     
-    def reporting_print_x_fields(self, collection, report_type, 
report_fields, report_noheaders):
+    def reporting_print_all_fields_item(self, item, report_type, 
report_noheaders):
+        """
+        Prints all fields for an item as a table given the report type
+        """
+        data = []
+        out_order = []
+        count = 0
+        x = {}
+        structure = item.to_datastruct()
+           
+        for (key, value) in structure.iteritems():
+
+            # exception for systems which could have > 1 interface
+            if key == "interfaces":
+                for (device, info) in value.iteritems():
+                    for (info_header, info_value) in info.iteritems():
+                        x[info_header] = str(device) + ': ' + 
str(info_value)
+                        # needs to create order list for 
print_formatted_fields
+                        if count == 0:
+                            out_order.append(info_header)
+            else:
+                x[key] = value
+                # needs to create order list for print_formatted_fields
+                if count == 0:
+                    out_order.append(key)                  
+
+        count = count + 1
+  
+        data.append(x)
+
+        self.print_formatted_data(data = data, order = out_order, 
report_type = report_type, noheaders = report_noheaders)
+        
+        return True
+
+    def reporting_print_x_fields_collection(self, collection, 
report_type, report_fields, report_noheaders):
         """
         Prints specific fields in a collection as a table given the 
report type
         """
@@ -281,6 +315,34 @@ class Report:
                         
         return True
         
+    def reporting_print_x_fields_item(self, item, report_type, 
report_fields, report_noheaders):
+        """
+        Prints specific fields for an item as a table given the report type
+        """
+        data = []
+        fields_list = report_fields.replace(' ', '').split(',')
+        
+        structure = item.to_datastruct()
+        x = {}
+        for field in fields_list:
+
+            if field in structure.keys():
+                x[field] = structure[field]
+
+            # exception for systems which could have > 1 interface
+            elif "interfaces" in structure.keys():
+                for device in structure['interfaces'].keys():
+                    if field in structure['interfaces'][device]:
+                        x[field] = device + ': ' + 
structure['interfaces'][device][field]                    
+            else:
+                raise CX(_("The field %s does not exist, see cobbler 
dumpvars for available fields.") % field)
+
+        data.append(x)
+         
+        self.print_formatted_data(data = data, order = fields_list, 
report_type = report_type, noheaders = report_noheaders)
+                        
+        return True
+
     # -------------------------------------------------------
 
     def run(self, report_what = None, report_name = None, report_type = 
None, report_fields = None, report_noheaders = None):
@@ -330,36 +392,44 @@ class Report:
         elif report_type == 'text' and report_fields != 'all':
             raise CX(_("The 'text' type can only be used with field set 
to 'all'"))
 
-        elif report_type != 'text' and report_fields == 'all':
+        # for a collection
+        elif report_type != 'text' and report_fields == 'all' and 
report_what:
             
             if report_what in [ "all", "distros", "distro" ]:
-                self.reporting_print_all_fields(self.api.distros(), 
report_type, report_noheaders)
+                
self.reporting_print_all_fields_collection(self.api.distros(), 
report_type, report_noheaders)
 
             if report_what in [ "all", "profiles", "profile" ]:
-                self.reporting_print_all_fields(self.api.profiles(), 
report_type, report_noheaders)
+                
self.reporting_print_all_fields_collection(self.api.profiles(), 
report_type, report_noheaders)
 
             if report_what in [ "all", "systems", "system" ]:
-                self.reporting_print_all_fields(self.api.systems(), 
report_type, report_noheaders)
+                
self.reporting_print_all_fields_collection(self.api.systems(), 
report_type, report_noheaders)
 
             if report_what in [ "all", "repos", "repo" ]:
-                self.reporting_print_all_fields(self.api.repos(), 
report_type, report_noheaders)
+                
self.reporting_print_all_fields_collection(self.api.repos(), 
report_type, report_noheaders)
 
             if report_what in [ "all", "images", "image" ]:
-                self.reporting_print_all_fields(self.api.images(), 
report_type, report_noheaders)
+                
self.reporting_print_all_fields_collection(self.api.images(), 
report_type, report_noheaders)
         
-        else:
+        # for an item
+        elif report_type != 'text' and report_fields == 'all':
+            
+            self.reporting_print_all_fields_item(report_name, 
report_type, report_noheaders)
+
+        elif report_what:
             
             if report_what in [ "all", "distros", "distro" ]:
-                self.reporting_print_x_fields(self.api.distros(), 
report_type, report_fields, report_noheaders)
+                
self.reporting_print_x_fields_collection(self.api.distros(), 
report_type, report_fields, report_noheaders)
 
             if report_what in [ "all", "profiles", "profile" ]:
-                self.reporting_print_x_fields(self.api.profiles(), 
report_type, report_fields, report_noheaders)
+                
self.reporting_print_x_fields_collection(self.api.profiles(), 
report_type, report_fields, report_noheaders)
 
             if report_what in [ "all", "systems", "system" ]:
-                self.reporting_print_x_fields(self.api.systems(), 
report_type, report_fields, report_noheaders)
+                
self.reporting_print_x_fields_collection(self.api.systems(), 
report_type, report_fields, report_noheaders)
 
             if report_what in [ "all", "repos", "repo" ]:
-                self.reporting_print_x_fields(self.api.repos(), 
report_type, report_fields, report_noheaders)
+                
self.reporting_print_x_fields_collection(self.api.repos(), report_type, 
report_fields, report_noheaders)
             if report_what in [ "all", "images", "image" ]:
-                self.reporting_print_x_fields(self.api.images(), 
report_type, report_fields, report_noheaders)
+                
self.reporting_print_x_fields_collection(self.api.images(), report_type, 
report_fields, report_noheaders)
+        else:
 
+            self.reporting_print_x_fields_item(report_name, 
report_type, report_fields, report_noheaders)
  
    

_______________________________________________
cobbler-devel mailing list
cobbler-devel@lists.fedorahosted.org
https://fedorahosted.org/mailman/listinfo/cobbler-devel