-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I hope this patch will actually work. Please, ignore any of my previous
patches, which should be easy enough since it didn't work to begin with.
If this patch doesn't work, I might be doing something wrong with git,
and help will be appreciated.
AS
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
iD8DBQFI0AIoECmX3C4JWKgRApx2AJ9F9jgDmghc+3Vaj/5/WjpYHsTZGACdEHVK
OhHFkm4AmpBHbLir1cb6ck0=
=h3/N
-----END PGP SIGNATURE-----
>From 5eb0ea8554567ae3b03cac66a8e79b46622a6d9f Mon Sep 17 00:00:00 2001
From: Anderson Silva <[EMAIL PROTECTED]>
Date: Tue, 16 Sep 2008 14:54:49 -0400
Subject: [PATCH] cobbler report changes
---
cobbler/action_report.py | 339 +++++++++++++++++++++++++++++++++++++++++
cobbler/api.py | 9 +
cobbler/commands.py | 32 +----
cobbler/modules/cli_misc.py | 52 -------
cobbler/modules/cli_report.py | 66 ++++++++
5 files changed, 418 insertions(+), 80 deletions(-)
create mode 100644 cobbler/action_report.py
create mode 100644 cobbler/modules/cli_report.py
diff --git a/cobbler/action_report.py b/cobbler/action_report.py
new file mode 100644
index 0000000..b56e582
--- /dev/null
+++ b/cobbler/action_report.py
@@ -0,0 +1,339 @@
+"""
+Report from a cobbler master.
+
+Copyright 2007-2008, Red Hat, Inc
+Anderson Silva <[EMAIL PROTECTED]>
+
+
+This software may be freely redistributed under the terms of the GNU
+general public license.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+"""
+
+import os
+import os.path
+import xmlrpclib
+import api as cobbler_api
+from cexceptions import *
+from utils import _
+
+
+class Report:
+
+ def __init__(self, config):
+ """
+ Constructor
+ """
+ self.config = config
+ self.settings = config.settings()
+ self.api = config.api
+ self.report_type = None
+ self.report_what = None
+ self.report_name = None
+ self.report_fields = None
+
+ def reporting_csv(self, info, order):
+ """
+ Formats data on 'info' for csv output
+ """
+ outputheaders = ''
+ outputbody = ''
+ sep = ','
+
+ info_count = 0
+ for item in info:
+
+ item_count = 0
+ for key in order:
+
+ if info_count == 0:
+ outputheaders += str(key) + sep
+
+ outputbody += str(item[key]) + sep
+
+ item_count = item_count + 1
+
+ info_count = info_count + 1
+ outputbody += '\n'
+
+ outputheaders += '\n'
+ return outputheaders + outputbody
+
+ def reporting_trac(self, info, order):
+ """
+ Formats data on 'info' for trac wiki table output
+ """
+ outputheaders = ''
+ outputbody = ''
+ sep = '||'
+
+ print info
+ print order
+
+ info_count = 0
+ for item in info:
+
+ item_count = 0
+ for key in order:
+
+
+ if info_count == 0:
+ outputheaders += sep + str(key)
+
+ outputbody += sep + str(item[key])
+
+ item_count = item_count + 1
+
+ info_count = info_count + 1
+ outputbody += '||\n'
+
+ outputheaders += '||\n'
+ return outputheaders + outputbody
+
+ def reporting_doku(self, info, order):
+ """
+ Formats data on 'info' for doku wiki table output
+ """
+ outputheaders = ''
+ outputbody = ''
+ sep1 = '^'
+ sep2 = '|'
+
+
+ info_count = 0
+ for item in info:
+
+ item_count = 0
+ for key in order:
+
+ if info_count == 0:
+ outputheaders += sep1 + key
+
+ outputbody += sep2 + item[key]
+
+ item_count = item_count + 1
+
+ info_count = info_count + 1
+ outputbody += sep2 + '\n'
+
+ outputheaders += sep1 + '\n'
+ return outputheaders + outputbody
+
+ def reporting_mediawiki(self, info, order):
+ """
+ Formats data on 'info' for mediawiki table output
+ """
+ outputheaders = ''
+ outputbody = ''
+ opentable = '{| border="1"\n'
+ closetable = '|}\n'
+ sep1 = '||'
+ sep2 = '|'
+ sep3 = '|-'
+
+
+ info_count = 0
+ for item in info:
+
+ item_count = 0
+ for key in order:
+
+ if info_count == 0 and item_count == 0:
+ outputheaders += sep2 + key
+ elif info_count == 0:
+ outputheaders += sep1 + key
+
+ if item_count == 0:
+ outputbody += sep2 + item[key]
+ else:
+ outputbody += sep1 + item[key]
+
+ item_count = item_count + 1
+
+ info_count = info_count + 1
+ outputbody += '\n' + sep3 + '\n'
+
+ outputheaders += '\n' + sep3 + '\n'
+ return opentable + outputheaders + outputbody + closetable
+
+ def print_formatted_data(self, data, order, report_type):
+ """
+ Used for picking the correct format to output data as
+ """
+ if report_type == "csv":
+ print self.reporting_csv(data, order)
+ if report_type == "mediawiki":
+ print self.reporting_mediawiki(data, order)
+ if report_type == "trac":
+ print self.reporting_trac(data, order)
+ if report_type == "doku":
+ print self.reporting_doku(data, order)
+
+ return True
+
+ def reporting_sorter(self, a, b):
+ """
+ Used for sorting cobbler objects for report commands
+ """
+ return cmp(a.name, b.name)
+
+ def reporting_print_sorted(self, collection):
+ """
+ Prints all objects in a collection sorted by name
+ """
+ collection = [x for x in collection]
+ collection.sort(self.reporting_sorter)
+ for x in collection:
+ print x.printable()
+ return True
+
+ def reporting_list_names2(self, collection, name):
+ """
+ Prints a specific object in a collection.
+ """
+ obj = collection.find(name=name)
+ if obj is not None:
+ print obj.printable()
+ return True
+
+ def reporting_print_all_fields(self, collection, report_type):
+ """
+ Prints all fields in a collection as a table given the report type
+ """
+ collection = [x for x in collection]
+ collection.sort(self.reporting_sorter)
+ data = []
+ out_order = []
+ count = 0
+ for x in collection:
+ item = {}
+ structure = x.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():
+ item[info_header] = device + ': ' + info_value
+ # needs to create order list for print_formatted_fields
+ if count == 0:
+ out_order.append(info_header)
+ else:
+ item[key] = value
+ # needs to create order list for print_formatted_fields
+ if count == 0:
+ out_order.append(key)
+
+ count = count + 1
+
+ data.append(item)
+
+ self.print_formatted_data(data = data, order = out_order, report_type = report_type)
+
+ return True
+
+ def reporting_print_x_fields(self, collection, report_type, report_fields):
+ """
+ Prints specific fields in a collection as a table given the report type
+ """
+ collection = [x for x in collection]
+ collection.sort(self.reporting_sorter)
+ data = []
+ fields_list = report_fields.replace(' ', '').split(',')
+
+ for x in collection:
+ structure = x.to_datastruct()
+ item = {}
+ for field in fields_list:
+
+ if field in structure.keys():
+ item[field] = structure[field]
+
+ # exception for systems which could have > 1 interface
+ if "interfaces" in structure.keys():
+ for device in structure['interfaces'].keys():
+ if field in structure['interfaces'][device]:
+ item[field] = device + ': ' + structure['interfaces'][device][field]
+ else:
+ raise CX(_("The field you are looking for most likely doesn't exist. Try dumpvars."))
+
+ data.append(item)
+
+ self.print_formatted_data(data = data, order = fields_list, report_type = report_type)
+
+ return True
+
+ # -------------------------------------------------------
+
+ def run(self, report_what = None, report_name = None, report_type = None, report_fields = None):
+ """
+ Get remote profiles and distros and sync them locally
+ """
+
+ """
+ 1. Handles original report output
+ 2. Handles all fields of report outputs as table given a format
+ 3. Handles specific fields of report outputs as table given a format
+ """
+
+
+ if report_type == 'text' and report_fields == 'all':
+
+ if report_what in [ "all", "distros", "distro" ]:
+ if report_name:
+ self.reporting_list_names2(self.api.distros(), report_name)
+ else:
+ self.reporting_print_sorted(self.api.distros())
+
+ if report_what in [ "all", "profiles", "profile" ]:
+ if report_name:
+ self.reporting_list_names2(self.api.profiles(), report_name)
+ else:
+ self.reporting_print_sorted(self.api.profiles())
+
+ if report_what in [ "all", "systems", "system" ]:
+ if report_name:
+ self.reporting_list_names2(self.api.systems(), report_name)
+ else:
+ self.reporting_print_sorted(self.api.systems())
+
+ if report_what in [ "all", "repos", "repo" ]:
+ if report_name is not None:
+ self.reporting_list_names2(self.api.repos(), report_name)
+ else:
+ self.reporting_print_sorted(self.api.repos())
+
+ 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':
+
+ if report_what in [ "all", "distros", "distro" ]:
+ self.reporting_print_all_fields(self.api.distros(), report_type)
+
+ if report_what in [ "all", "profiles", "profile" ]:
+ self.reporting_print_all_fields(self.api.profiles(), report_type)
+
+ if report_what in [ "all", "systems", "system" ]:
+ self.reporting_print_all_fields(self.api.systems(), report_type)
+
+ if report_what in [ "all", "repos", "repo" ]:
+ self.reporting_print_all_fields(self.api.repos(), report_type)
+
+ else:
+
+ if report_what in [ "all", "distros", "distro" ]:
+ self.reporting_print_x_fields(self.api.distros(), report_type, report_fields)
+
+ if report_what in [ "all", "profiles", "profile" ]:
+ self.reporting_print_x_fields(self.api.profiles(), report_type, report_fields)
+
+ if report_what in [ "all", "systems", "system" ]:
+ self.reporting_print_x_fields(self.api.systems(), report_type, report_fields)
+
+ if report_what in [ "all", "repos", "repo" ]:
+ self.reporting_print_x_fields(self.api.repos(), report_type, report_fields)
diff --git a/cobbler/api.py b/cobbler/api.py
index f0ade5d..eaf71b6 100644
--- a/cobbler/api.py
+++ b/cobbler/api.py
@@ -33,6 +33,7 @@ import action_validate
import action_buildiso
import action_replicate
import action_acl
+import action_report
from cexceptions import *
import sub_process
import module_loader
@@ -521,6 +522,14 @@ class BootAPI:
include_systems = systems
)
+ def report(self, report_what = None, report_name = None, report_type = None, report_fields = None):
+ """
+ Report functionality for cobbler
+ """
+ reporter = action_report.Report(self._config)
+ return reporter.run(report_what = report_what, report_name = report_name,\
+ report_type = report_type, report_fields = report_fields)
+
def get_kickstart_templates(self):
return utils.get_kickstar_templates(self)
diff --git a/cobbler/commands.py b/cobbler/commands.py
index bee233c..6a3c38d 100644
--- a/cobbler/commands.py
+++ b/cobbler/commands.py
@@ -291,10 +291,11 @@ class CobblerFunction:
if "report" in self.args:
if self.options.name is None:
- self.reporting_print_sorted(collect_fn())
+ return self.api.report(report_what = self.args[1], report_name = self.options.name, \
+ report_type = 'text', report_fields = 'all')
else:
- self.reporting_list_names2(collect_fn(),self.options.name)
- return None
+ return self.api.report(report_what = self.args[1], report_name = 'all', \
+ report_type = 'text', report_fields = 'all')
if "getks" in self.args:
if not self.options.name:
@@ -396,31 +397,6 @@ class CobblerFunction:
return rc
- def reporting_sorter(self, a, b):
- """
- Used for sorting cobbler objects for report commands
- """
- return cmp(a.name, b.name)
-
- def reporting_print_sorted(self, collection):
- """
- Prints all objects in a collection sorted by name
- """
- collection = [x for x in collection]
- collection.sort(self.reporting_sorter)
- for x in collection:
- print x.printable()
- return True
-
- def reporting_list_names2(self, collection, name):
- """
- Prints a specific object in a collection.
- """
- obj = collection.find(name=name)
- if obj is not None:
- print obj.printable()
- return True
-
def list_tree(self,collection,level):
"""
Print cobbler object tree as a, well, tree.
diff --git a/cobbler/modules/cli_misc.py b/cobbler/modules/cli_misc.py
index fdc8d69..f2d9042 100644
--- a/cobbler/modules/cli_misc.py
+++ b/cobbler/modules/cli_misc.py
@@ -148,58 +148,6 @@ class ListFunction(commands.CobblerFunction):
########################################################
-class ReportFunction(commands.CobblerFunction):
-
- def help_me(self):
- return HELP_FORMAT % ("cobbler report","[ARGS|--help]")
-
- def command_name(self):
- return "report"
-
- def add_options(self, p, args):
- p.add_option("--what", dest="what", default="all", help="distros/profiles/systems/repos")
- p.add_option("--name", dest="name", help="report on just this object")
-
- def run(self):
- if self.options.what not in [ "all", "distros", "profiles", "systems", "repos", "images" ]:
- raise CX(_("Invalid value for --what"))
-
- if self.options.what in [ "all", "distros" ]:
- if self.options.name:
- self.reporting_list_names2(self.api.distros(),self.options.name)
- else:
- self.reporting_print_sorted(self.api.distros())
-
- if self.options.what in [ "all", "profiles" ]:
- if self.options.name:
- self.reporting_list_names2(self.api.profiles(),self.options.name)
- else:
- self.reporting_print_sorted(self.api.profiles())
-
- if self.options.what in [ "all", "systems" ]:
- if self.options.name:
- self.reporting_list_names2(self.api.systems(),self.options.name)
- else:
- self.reporting_print_sorted(self.api.systems())
-
- if self.options.what in [ "all", "repos" ]:
- if self.options.name:
- self.reporting_list_names2(self.api.repos(),self.options.name)
- else:
- self.reporting_print_sorted(self.api.repos())
-
- if self.options.what in [ "all", "images" ]:
- if self.options.name:
- self.reporting_list_names2(self.api.images(),self.options.name)
- else:
- self.reporting_print_sorted(self.api.images())
-
- return True
-
-
-
-########################################################
-
class StatusFunction(commands.CobblerFunction):
def help_me(self):
diff --git a/cobbler/modules/cli_report.py b/cobbler/modules/cli_report.py
new file mode 100644
index 0000000..420da09
--- /dev/null
+++ b/cobbler/modules/cli_report.py
@@ -0,0 +1,66 @@
+"""
+Report CLI module.
+
+Copyright 2008, Red Hat, Inc
+Anderson Silva <[EMAIL PROTECTED]
+
+This software may be freely redistributed under the terms of the GNU
+general public license.:
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+"""
+
+import distutils.sysconfig
+import sys
+
+plib = distutils.sysconfig.get_python_lib()
+mod_path="%s/cobbler" % plib
+sys.path.insert(0, mod_path)
+
+from utils import _, get_random_mac
+import commands
+from cexceptions import *
+HELP_FORMAT = commands.HELP_FORMAT
+
+
+class ReportFunction(commands.CobblerFunction):
+
+ def help_me(self):
+ return HELP_FORMAT % ("cobbler report","[ARGS|--help]")
+
+ def command_name(self):
+ return "report"
+
+ def add_options(self, p, args):
+ p.add_option("--what", dest="what", default="all", help="distros/profiles/systems/repos")
+ p.add_option("--name", dest="name", help="report on just this object")
+ p.add_option("--type", dest="type", default="text", help="text/csv/trac/doku/mediawiki")
+ p.add_option("--fields", dest="fields", default="all" , help="what fields to display")
+
+
+ def run(self):
+ if self.options.what not in [ "all", "distros", "profiles", "systems", "repos" ]:
+ raise CX(_("Invalid value for --what"))
+ if self.options.type not in ["text", "csv", "trac", "doku", "mediawiki" ]:
+ raise CX(_("Invalid vavlue for --type"))
+
+ return self.api.report(report_what = self.options.what, report_name = self.options.name, \
+ report_type = self.options.type, report_fields = self.options.fields)
+
+########################################################
+# MODULE HOOKS
+
+def register():
+ """
+ The mandatory cobbler module registration hook.
+ """
+ return "cli"
+
+def cli_functions(api):
+ return [
+ ReportFunction(api)
+ ]
+
+
--
1.5.4.1
_______________________________________________
cobbler mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/cobbler