"""
.. versionadded:: 0.6.0
Requires SMC version >= 6.3
Reports generated from the SMC. Provides an interface to running existing report
designs and exporting their contents.
Example usage::
>>> from smc.administration.reports import ReportDesign, ReportTemplate, Report
List all available report templates::
>>> list(ReportTemplate.objects.all())
[ReportTemplate(name=Firewall Weekly Summary),
ReportTemplate(name=Firewall Daily Summary from Specific Firewall),
ReportTemplate(name=Firewall Multi-Link Usage)
...
Create a report design using an existing report template::
>>> template = ReportTemplate('Firewall Weekly Summary')
>>> template.create_design('myfirewallreport')
ReportDesign(name=myfirewallreport)
Generate a report based on an existing or created report design::
>>> list(ReportDesign.objects.all())
[ReportDesign(name=Application and Web Security), ReportDesign(name=myfirewallreport)]
...
>>> design = ReportDesign('Application and Web Security')
>>> poller = design.generate(wait_for_finish=True)
>>> while not poller.done():
... poller.wait(3)
...
>>> poller.task.resource
>>> Report(name=Application and Web Security #1515295820751)
...
>>> design.report_files
[Report(name=Application and Web Security #1515295820751), Report(name=Application and Web Security #1515360776422)]
>>> report = Report('Application and Web Security #1515360776422')
>>> print(report.creation_time)
2018-01-07 15:32:56.422000
>>> report.export_pdf(filename='/foo/bar/a.pdf')
"""
from smc.base.model import Element
from smc.administration.tasks import Task
from smc.base.util import datetime_from_ms, element_resolver
from smc.api.exceptions import CreateElementFailed
[docs]class ReportDesign(Element):
"""
A ReportDesign defines a report available in the SMC. This class provides access
to generating these reports and exporting into a format supported by the SMC.
Example of generating a report, and providing a callback once the report is complete
which exports the report::
>>> def export_my_report(task):
... if task.resource:
... report = task.resource[0]
... print("My report reference: %s" % report)
... report.export_pdf('/Users/foo/myfile.pdf')
...
>>>
>>> report = ReportDesign('Application and Web Security')
>>> poller = report.generate(wait_for_finish=True)
>>> poller.add_done_callback(export_my_report)
>>> while not poller.done():
... poller.wait(3)
...
My report reference: Report(name=Application and Web Security #1515375369483)
"""
typeof = 'report_design'
[docs] def generate(self, start_time=0, end_time=0,
senders=None, wait_for_finish=False, timeout=5, **kw): # @ReservedAssignment
"""
Generate the report and optionally wait for results.
You can optionally add filters to the report by providing the senders
argument as a list of type Element::
report = ReportDesign('Firewall Weekly Summary')
begin = datetime_to_ms(datetime.strptime("2018-02-03T00:00:00", "%Y-%m-%dT%H:%M:%S"))
end = datetime_to_ms(datetime.strptime("2018-02-04T00:00:00", "%Y-%m-%dT%H:%M:%S"))
report.generate(start_time=begin, end_time=end, senders=[Engine('vm')])
:param int period_begin: milliseconds time defining start time for report
:param int period_end: milliseconds time defining end time for report
:param senders: filter targets to use when generating report
:type senders: list(Element)
:param bool wait_for_finish: enable polling for results
:param int timeout: timeout between polling
:raises TaskRunFailed: refresh failed, possibly locked policy
:rtype: TaskOperationPoller
"""
if start_time and end_time:
kw.setdefault('params', {}).update(
{'start_time': start_time,
'end_time': end_time})
if senders:
kw.setdefault('json', {}).update({'senders': element_resolver(senders)})
return Task.execute(self, 'generate',
timeout=timeout, wait_for_finish=wait_for_finish, **kw)
@property
def report_files(self):
"""
Retrieve all reports that are currently available on the SMC.
:rtype: list(Report)
"""
return [Report(**report) for report in self.make_request(
resource='report_files')]
[docs]class ReportTemplate(Element):
"""
A report template represents an existing template in the SMC. Templates can
be retrieved through the normal collections::
>>> list(ReportTemplate.objects.all())
[ReportTemplate(name=Firewall Weekly Summary),
ReportTemplate(name=Firewall Daily Summary from Specific Firewall),
ReportTemplate(name=Firewall Multi-Link Usage)
...
Once a report template of interest is identified, you can create a
ReportDesign using that template::
>>> template = ReportTemplate('Firewall Weekly Summary')
>>> template.create_design('myfirewallreport')
ReportDesign(name=myfirewallreport)
"""
typeof = 'report_template'
[docs] def create_design(self, name):
"""
Create a report design based on an existing template.
:param str name: Name of new report design
:raises CreateElementFailed: failed to create template
:rtype: ReportDesign
"""
result = self.make_request(
CreateElementFailed,
resource='create_design',
raw_result=True,
method='create',
params={'name': name})
return ReportDesign(
href=result.href, type=self.typeof, name=name)
[docs]class Report(Element):
"""
Report represent a report that has been generated and that is
currently stored on the SMC. These reports can be exported in multiple
formats.
"""
typeof = 'report_file'
@property
def creation_time(self):
"""
When this report was generated. Using local time.
:rtype: datetime.datetime
"""
return datetime_from_ms(self.data.get('creation_time'))
@property
def period_begin(self):
"""
Period when this report was specified to start.
:rtype: datetime.datetime
"""
return datetime_from_ms(self.data.get('period_begin'))
@property
def period_end(self):
"""
Period when this report was specified to end.
:rtype: datetime.datetime
"""
return datetime_from_ms(self.data.get('period_end'))
[docs] def export_pdf(self, filename):
"""
Export the report in PDF format. Specify a path for which
to save the file, including the trailing filename.
:param str filename: path including filename
:return: None
"""
self.make_request(
raw_result=True,
resource='export',
filename=filename,
headers = {'accept': 'application/pdf'})
[docs] def export_text(self, filename=None):
"""
Export in text format. Optionally provide a filename to
save to.
:param str filename: path including filename (optional)
:return: None
"""
result = self.make_request(
resource='export',
params={'format': 'txt'},
filename=filename,
raw_result=True,
headers = {'accept': 'text/plain'})
if not filename:
return result.content