コード例 #1
0
    def _renderView(self, pdfRenderer, view, lastView=False):
        """ render an individual panel """

        types = view.getRenderTypes()
        pdfRenderer.conditionalPageBreak(types)

        # always render header first
        self._renderViewHeader(pdfRenderer, view)

        if view.hasError():
            pdfRenderer.renderText(view.getError())
            return
        if view.requiresSearchJobObj():
            if view.hasSearchError():
                pdfRenderer.renderText(view.getSearchError())
                return
            while not view.isSearchComplete() and not view.isRealtime():
                time.sleep(self.POLLING_WAIT_TIME)
                self._keepAllSearchesAlive()
                self._checkForTimeout()

        if 'trellis.enabled' in view.getOptions() and normalizeBoolean(
                view.getOptions()['trellis.enabled']):
            pdfRenderer.renderText(
                "PDF export is not available for visualizations using trellis layout."
            )
        else:
            try:
                for type in types:
                    if type == 'chart':
                        self._renderChart(pdfRenderer, view)
                    elif type == 'map':
                        self._renderMap(pdfRenderer, view)
                    elif type == 'table':
                        self._renderTable(pdfRenderer, view)
                    elif type == 'event':
                        self._renderEvents(pdfRenderer, view)
                    elif type == 'single':
                        self._renderSingle(pdfRenderer, view)
                    elif type == 'list':
                        self._renderList(pdfRenderer, view)
                    elif type == 'html':
                        self._renderHtml(pdfRenderer, view)
                    elif type == 'viz':
                        pdfRenderer.renderText(
                            "PDF export does not support custom visualizations."
                        )
                    else:
                        pdfRenderer.renderText(
                            "No render option for type '%s'" % type)
                        logger.warning(
                            "PDFGenHandler::_renderView> No render option for type = '%s'"
                            % type)
            except Exception as e:
                content = str(e)
                pu.logErrorAndTrace(e)
                pdfRenderer.renderText(content)

        if not lastView:
            pdfRenderer.spaceBetween()
コード例 #2
0
    def _render(self):
        try:
            self._inactiveViews = self._views[:]
            for _ in range(3):
                self._startNextSearch()
        except Exception, e:

            errorMsg = \
                'Exception raised while trying to prepare "%s" for rendering to PDF. %s' \
                % (self._title, e)
            pu.logErrorAndTrace(errorMsg)
            self._outputError([errorMsg])
            return False
コード例 #3
0
    def _handleRequest(self):
        logger.debug("pdfgen/render request: " + str(self.request))

        if not self._initialize():
            return

        if self.method == 'GET' and not self._enableInsecurePdfgen:
            errorMsg = "pdfgen GET is deprecated. Please use POST instead."
            pu.logErrorAndTrace(errorMsg)
            self._outputError([errorMsg])
            return

        if not self._render():
            return

        self._respond()
コード例 #4
0
    def _initialize(self):
        try:
            self._initParameters()

            if self._viewType == self.VIEW_TYPE_DASHBOARD:
                # handle Xml vs. entity name
                logger.debug("dashboardName=%s dashboardXml=%s" % (self._dashboardName, self._dashboardXml))
                if self._dashboardXml != None:
                    (self._title, self._description, self._views) = pv.getDashboardTitleAndPanelsFromXml(
                        dashboardXml=self._dashboardXml,
                        namespace=self._namespace,
                        owner=self._owner,
                        sessionKey=self.sessionKey)
                elif self._dashboardName != None:
                    (self._title, self._description, self._views) = pv.getDashboardTitleAndPanels(
                        dashboard_name=self._dashboardName, 
                        namespace=self._namespace, 
                        owner=self._owner, 
                        sessionKey=self.sessionKey)
            elif self._viewType == self.VIEW_TYPE_REPORT:
                self._views.append(pv.Report(savedSearchName=self._reportName, namespace=self._namespace, owner=self._owner, sessionKey=self.sessionKey))
                self._title = self._reportName
            elif self._viewType == self.VIEW_TYPE_SEARCH:
                self._title = self._reportName
                self._views.append(pv.SearchReport(search=self._searchStr, et=self._et, lt=self._lt, title=self._title, namespace=self._namespace, owner=self._owner, sessionKey=self.sessionKey))

            self._handlePresetSearchIDs()
            
            # instantiate the pdfRenderer object with a file-like object
            self._pdfBuffer = cStringIO.StringIO()
            self._pdfRenderer = pdfrenderer.PDFRenderer(namespace=self._namespace, title=self._title,
                                                        description=self._description, outputFile=self._pdfBuffer,
                                                        paperSize=self._paperSize, timestamp=self._timestampStr,
                                                        includeSplunkLogo=self._includeSplunkLogo,
                                                        cidFontList=self._cidFontList, pdfSettings=self._pdfSettings,
                                                        requestSettings=self._requestSettings)
            return True
        except ArgError as e:
            self.response.setStatus(400)
            self.response.write(e.message)
        except Exception as e:
            errorMsg = "Bailing out of Integrated PDF Generation. Exception raised while preparing to render \"%s\" to PDF. %s" % (self._title, e)
            pu.logErrorAndTrace(errorMsg)
            self._outputError([errorMsg])
        return False
コード例 #5
0
 def _respond(self):
     # save and write out the file
     try:
         self.response.write(self._pdfBuffer.getvalue().decode('ISO 8859-1'))
         self.response.setHeader('content-type', 'application/pdf')
         # override normal cache-control header to fix problem on ie6-ie8 (see SPL-50739)
         self.response.setHeader('cache-control', 'max-age=0, must-revalidate')
         name = self._generateFileName()
         logger.info('Generated pdf, filename = %s' % name)
         disposition = 'inline' if self.ARG_DISPLAY_INLINE in self.args else 'attachment'
         self.response.setHeader('content-disposition',
                                 disposition + '; filename="' + name + '"')
         self.response.setStatus(200)
         self._pdfBuffer.close()
     except Exception as e:
         errorMsg = "Exception raised while trying to respond. Bailing out of Integrated PDF Generation. Rendering \"%s\" to PDF. %s" % (self._title, e)
         pu.logErrorAndTrace(errorMsg)
         self._outputError([errorMsg])
         return False
     return True
コード例 #6
0
    def _render(self):
        try:
            self._inactiveViews = self._views[:]
            for _ in range(3):
                self._startNextSearch()

        except Exception as e:
            errorMsg = "Exception raised while trying to prepare \"%s\" for rendering to PDF. %s" % (self._title, e)
            pu.logErrorAndTrace(errorMsg)
            self._outputError([errorMsg])
            return False

        # iterate over views and render each to the pdf
        viewPrepErrors = []
        for i, view in enumerate(self._views):
            try:
                self._keepAllSearchesAlive()
                self._checkForTimeout()
               
                isLastView = (i == len(self._views) - 1) 
                self._renderView(self._pdfRenderer, view, lastView = isLastView)
                
                self._startNextSearch()

            except TimeoutError:
                errorMsg = "Timeout while trying to prepare \"%s\" for rendering to PDF." % self._title
                self._outputTimeoutError(errorMsg)
                return
            except Exception as e:
                errorMsg = "Exception raised while trying to prepare \"%s\" for rendering to PDF. %s" % (self._title, e)
                pu.logErrorAndTrace(errorMsg)
                viewPrepErrors.append(errorMsg)
        if len(self._views) == 0:
            # fix SPL-67268, render a empty dashboard if there's 0 views
            self._pdfRenderer.renderText("")

        # if we weren't able to render any views successfully, output an error as response to endpoint
        if len(viewPrepErrors) == len(self._views) and len(self._views) > 0:
            self._outputError(viewPrepErrors)
            logger.error("No views prepared without exceptions. Bailing out of Integrated PDF Generation.")
            return False
            
        try:
            self._pdfRenderer.save()
        except Exception as e:
            errorMsg = []
            errorMsg.append("Exception raised while trying to render \"%s\" to PDF." % (self._title))

            # SPL-80872 - [PDF] Cannot render PDF report of A5 size if the table is too big
            if "too large on page" in e.message:
                errorMsg.append("Please try using a larger paper size than %s." % (self._paperSize))

            errorMsg.append("%s" % (e))
            pu.logErrorAndTrace(errorMsg)
            self._outputError(errorMsg)
            return False

        return True
コード例 #7
0
class PDFGenHandler(splunk.rest.BaseRestHandler):

    _args = {}
    _deletePdfFileAfterSettingResponse = True
    _timeoutTime = None

    _views = []
    _inputSids = {}

    _title = 'Untitled'
    _description = ''
    _dashboardName = None
    _dashboardXml = None
    _reportName = None
    _viewType = None
    _paperSize = DEFAULT_PAPER_SIZE
    _namespace = None
    _owner = None
    _timeoutDuration = DEFAULT_TIMEOUT
    _maxRowsPerTable = DEFAULT_MAX_ROWS_PER_TABLE
    _includeSplunkLogo = DEFAULT_INCLUDE_SPLUNK_LOGO
    _cidFontList = None
    _now = None
    _timestampStr = ''
    _searchStr = None
    _et = ''
    _lt = ''
    _inactiveViews = None
    _fileNamePattern = None

    _touchSearchJobsLastTime = None
    _pdfBuffer = None
    _pdfRenderer = None

    VIEW_TYPE_DASHBOARD = 'dashboard'
    VIEW_TYPE_REPORT = 'report'
    VIEW_TYPE_SEARCH = 'search'

    ARG_INPUT_DASHBOARD = 'input-dashboard'
    ARG_INPUT_DASHBOARD_XML = 'input-dashboard-xml'
    ARG_INPUT_REPORT = 'input-report'
    ARG_INPUT_SEARCH = 'input-search'
    ARG_INPUT_LOCALE = 'locale'
    ARG_INPUT_ET = 'et'
    ARG_INPUT_LT = 'lt'
    ARG_INPUT_PAPERSIZE = 'paper-size'
    ARG_INPUT_SID = 'sid'
    ARG_INPUT_NAMESPACE = 'namespace'
    ARG_INPUT_OWNER = 'owner'
    ARG_INPUT_TIMEOUT = 'timeout'
    ARG_INPUT_MAX_ROWS_PER_TABLE = 'max-rows-per-table'
    ARG_INPUT_INCLUDE_SPLUNK_LOGO = 'include-splunk-logo'
    ARG_INPUT_REPORT_FILE_NAME = 'report-file-name'
    ARG_INPUT_NOW = 'now'
    ARG_CACHE_BUSTER = '_'
    ARG_CSRF_FORM_KEY = 'splunk_form_key'

    _validArgs = [
        ARG_INPUT_DASHBOARD,
        ARG_INPUT_DASHBOARD_XML,
        ARG_INPUT_REPORT,
        ARG_INPUT_SEARCH,
        ARG_INPUT_ET,
        ARG_INPUT_LT,
        ARG_INPUT_PAPERSIZE,
        ARG_INPUT_SID,
        ARG_INPUT_NAMESPACE,
        ARG_INPUT_OWNER,
        ARG_INPUT_TIMEOUT,
        ARG_INPUT_MAX_ROWS_PER_TABLE,
        ARG_INPUT_INCLUDE_SPLUNK_LOGO,
        ARG_INPUT_NOW,
        ARG_CACHE_BUSTER,
        ARG_CSRF_FORM_KEY,
        ARG_INPUT_LOCALE,
    ]

    SID_VALIDATOR_STR = 'sid_([0-9]+)'
    sidRE = re.compile(SID_VALIDATOR_STR)

    POLLING_WAIT_TIME = 0.5
    TOUCH_SEARCH_INTERVAL = 10

    ALERT_ACTIONS_ENTITY = '/configs/conf-alert_actions'
    LIMITS_ENTITY = '/configs/conf-limits'
    WEB_ENTITY = '/configs/conf-web'

    def handle_GET(self):
        self._handleRequest()

    def handle_POST(self):
        self._handleRequest()

    def _handleRequest(self):
        logger.debug('pdfgen/render request: ' + str(self.request))

        if not self._initialize():
            return

        if not self._render():
            return

        self._respond()

    def _initialize(self):
        try:
            self._initParameters()

            if self._viewType == self.VIEW_TYPE_DASHBOARD:

                # handle Xml vs. entity name

                logger.debug('dashboardName=%s dashboardXml=%s' %
                             (self._dashboardName, self._dashboardXml))
                if self._dashboardXml != None:
                    (self._title, self._description, self._views) = \
                        pv.getDashboardTitleAndPanelsFromXml(dashboardXml=self._dashboardXml,
                            namespace=self._namespace,
                            owner=self._owner,
                            sessionKey=self.sessionKey)
                elif self._dashboardName != None:
                    (self._title, self._description, self._views) = \
                        pv.getDashboardTitleAndPanels(dashboard_name=self._dashboardName,
                            namespace=self._namespace,
                            owner=self._owner,
                            sessionKey=self.sessionKey)
            elif self._viewType == self.VIEW_TYPE_REPORT:
                self._views.append(
                    pv.Report(savedSearchName=self._reportName,
                              namespace=self._namespace,
                              owner=self._owner,
                              sessionKey=self.sessionKey))
                self._title = self._reportName
            elif self._viewType == self.VIEW_TYPE_SEARCH:
                self._title = self._reportName
                self._views.append(
                    pv.SearchReport(
                        search=self._searchStr,
                        et=self._et,
                        lt=self._lt,
                        title=self._title,
                        namespace=self._namespace,
                        owner=self._owner,
                        sessionKey=self.sessionKey,
                    ))

            self._handlePresetSearchIDs()

            # instantiate the pdfRenderer object with a file-like object

            self._pdfBuffer = cStringIO.StringIO()
            self._pdfRenderer = pdfrenderer.PDFRenderer(
                namespace=self._namespace,
                title=self._title,
                description=self._description,
                outputFile=self._pdfBuffer,
                paperSize=self._paperSize,
                timestamp=self._timestampStr,
                includeSplunkLogo=self._includeSplunkLogo,
                cidFontList=self._cidFontList,
                pdfSettings=self._pdfSettings,
            )
            return True
        except ArgError, e:
            self.response.setStatus(400)
            self.response.write(e.message)
        except Exception, e:
            errorMsg = \
                'Bailing out of Integrated PDF Generation. Exception raised while preparing to render "%s" to PDF. %s' \
                % (self._title, e)
            pu.logErrorAndTrace(errorMsg)
            self._outputError([errorMsg])
コード例 #8
0
                isLastView = i == len(self._views) - 1
                self._renderView(self._pdfRenderer, view, lastView=isLastView)

                self._startNextSearch()
            except TimeoutError:

                errorMsg = \
                    'Timeout while trying to prepare "%s" for rendering to PDF.' \
                    % self._title
                self._outputTimeoutError(errorMsg)
                return
            except Exception, e:
                errorMsg = \
                    'Exception raised while trying to prepare "%s" for rendering to PDF. %s' \
                    % (self._title, e)
                pu.logErrorAndTrace(errorMsg)
                viewPrepErrors.append(errorMsg)
        if len(self._views) == 0:

            # fix SPL-67268, render a empty dashboard if there's 0 views

            self._pdfRenderer.renderText('')

        # if we weren't able to render any views successfully, output an error as response to endpoint

        if len(viewPrepErrors) == len(self._views) and len(self._views) \
            > 0:
            self._outputError(viewPrepErrors)
            logger.error(
                'No views prepared without exceptions. Bailing out of Integrated PDF Generation.'
            )