"""
Report from a cobbler master.
FIXME: reinstante functionality for 2.0
"""
from past.builtins import cmp
from builtins import str
from builtins import object
import re
from cobbler import clogger
from cobbler import utils
[docs]class Report(object):
def __init__(self, collection_mgr, logger=None):
"""
Constructor
"""
self.collection_mgr = collection_mgr
self.settings = collection_mgr.settings()
self.api = collection_mgr.api
self.report_type = None
self.report_what = None
self.report_name = None
self.report_fields = None
self.report_noheaders = None
self.array_re = re.compile(r'([^[]+)\[([^]]+)\]')
if logger is None:
logger = clogger.Logger()
self.logger = logger
[docs] def fielder(self, structure, fields_list):
"""
Return data from a subset of fields of some item
"""
item = {}
for field in fields_list:
internal = self.array_re.search(field)
# check if field is primary field
if field in list(structure.keys()):
item[field] = structure[field]
# check if subfield in 'interfaces' field
elif internal and internal.group(1) in list(structure.keys()):
outer = internal.group(1)
inner = internal.group(2)
if isinstance(structure[outer], dict) and inner in structure[outer]:
item[field] = structure[outer][inner]
elif "interfaces" in list(structure.keys()):
for device in list(structure['interfaces'].keys()):
if field in structure['interfaces'][device]:
item[field] = device + ': ' + structure['interfaces'][device][field]
return item
[docs] def reporting_csv(self, info, order, noheaders):
"""
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
if key in list(item.keys()):
outputbody += str(item[key]) + sep
else:
outputbody += '-' + sep
item_count += 1
info_count += 1
outputbody += '\n'
outputheaders += '\n'
if noheaders:
outputheaders = ''
return outputheaders + outputbody
[docs] def reporting_trac(self, info, order, noheaders):
"""
Formats data on 'info' for trac wiki table output
"""
outputheaders = ''
outputbody = ''
sep = '||'
info_count = 0
for item in info:
item_count = 0
for key in order:
if info_count == 0:
outputheaders += sep + str(key)
if key in list(item.keys()):
outputbody += sep + str(item[key])
else:
outputbody += sep + '-'
item_count = item_count + 1
info_count = info_count + 1
outputbody += '||\n'
outputheaders += '||\n'
if noheaders:
outputheaders = ''
return outputheaders + outputbody
[docs] def reporting_doku(self, info, order, noheaders):
"""
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
if key in list(item.keys()):
outputbody += sep2 + item[key]
else:
outputbody += sep2 + '-'
item_count = item_count + 1
info_count = info_count + 1
outputbody += sep2 + '\n'
outputheaders += sep1 + '\n'
if noheaders:
outputheaders = ''
return outputheaders + outputbody
[docs] def reporting_sorter(self, a, b):
"""
Used for sorting cobbler objects for report commands
"""
return cmp(a.name, b.name)
[docs] 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:
self.logger.flat(x.to_string())
[docs] def reporting_list_names2(self, collection, name):
"""
Prints a specific object in a collection.
"""
obj = collection.get(name)
if obj is not None:
self.logger.flat(obj.to_string())
[docs] def reporting_print_all_fields(self, collection, report_name, report_type, report_noheaders):
"""
Prints all fields in a collection as a table given the report type
"""
# per-item hack
if report_name:
collection = collection.find(name=report_name)
if collection:
collection = [collection]
else:
return
collection = [x for x in collection]
collection.sort(self.reporting_sorter)
data = []
out_order = []
count = 0
for x in collection:
item = {}
if x.ITEM_TYPE == "settings":
structure = x.to_dict()
else:
structure = x.to_list()
for (key, value) in list(structure.items()):
# exception for systems which could have > 1 interface
if key == "interfaces":
for (device, info) in list(value.items()):
for (info_header, info_value) in list(info.items()):
item[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:
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, noheaders=report_noheaders)
[docs] def reporting_print_x_fields(self, collection, report_name, report_type, report_fields, report_noheaders):
"""
Prints specific fields in a collection as a table given the report type
"""
# per-item hack
if report_name:
collection = collection.find(name=report_name)
if collection:
collection = [collection]
else:
return
collection = [x for x in collection]
collection.sort(self.reporting_sorter)
data = []
fields_list = report_fields.replace(' ', '').split(',')
for x in collection:
if x.ITEM_TYPE == "settings":
structure = x.to_dict()
else:
structure = x.to_list()
item = self.fielder(structure, fields_list)
data.append(item)
self.print_formatted_data(data=data, order=fields_list, report_type=report_type, noheaders=report_noheaders)
# -------------------------------------------------------
[docs] def run(self, report_what=None, report_name=None, report_type=None, report_fields=None, report_noheaders=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':
for collection_name in ["distro", "profile", "system", "repo", "network", "image", "mgmtclass", "package", "file"]:
if report_what == "all" or report_what == collection_name or report_what == "%ss" % collection_name or report_what == "%ses" % collection_name:
if report_name:
self.reporting_list_names2(self.api.get_items(collection_name), report_name)
else:
self.reporting_print_sorted(self.api.get_items(collection_name))
elif report_type == 'text' and report_fields != 'all':
utils.die(self.logger, "The 'text' type can only be used with field set to 'all'")
elif report_type != 'text' and report_fields == 'all':
for collection_name in ["distro", "profile", "system", "repo", "network", "image", "mgmtclass", "package", "file"]:
if report_what == "all" or report_what == collection_name or report_what == "%ss" % collection_name or report_what == "%ses" % collection_name:
self.reporting_print_all_fields(self.api.get_items(collection_name), report_name, report_type, report_noheaders)
else:
for collection_name in ["distro", "profile", "system", "repo", "network", "image", "mgmtclass", "package", "file"]:
if report_what == "all" or report_what == collection_name or report_what == "%ss" % collection_name or report_what == "%ses" % collection_name:
self.reporting_print_x_fields(self.api.get_items(collection_name), report_name, report_type, report_fields, report_noheaders)