Custom fragments example

The custom fragments feature allows an app to inject its own content into QRadar® tabs and pages. The application determines what the content is and how it is rendered. The injection points are fixed, predetermined locations within the QRadar page set.

The sample app that is presented here injects an HTML table that contains data for an offense on the Offense Summary page. This example uses app/qpylib/offense_qpylib.py library functions to retrieve offense details in JSON format.

The following image shows custom content at the top of the Offense Summary page:

Figure 1. Custom content injection
custom content injection

The following sections describe the manifest.json and app/views.py code that is used to inject offense data into the Offense Summary page header.

manifest.json

Use the fragments block in the application manifest file to define the location where you want to inject the content. You also define the REST endpoint that is used to retrieve the content in the fragments.

{
	"name":"Offense Fragment New",
	"description":"Render offense using custom python",
	"version":"1.0",
	"uuid":"a4095969-1c88-4e35-aecb-4eea7b061ab4",

"fragments": [
    {
        "app_name": "SEM", 1 
        "page_id": "OffenseSummary",
        "rest_endpoint": "fragoffense" 2 
    }
  ]
}
The following list describes the contents in the code snippet from the fragments block.
  1. The app_name and page_id fields define the tab and page where the content is injected. As content can be injected into the header of the Offense Summary page only, no location field is required.
  2. The fragoffense rest endpoint is defined in the app/views.py file.

app/views.py

__author__ = 'IBM'

from flask import Response
from app import app
from qpylib.qpylib import log
from qpylib.offense_qpylib import get_offense_json_html 1 

@app.route('/fragoffense/<offense_id>', methods=['GET']) 2 
def get_offense(offense_id):
  try:
   offense_json = get_offense_json_html(offense_id, custom_html_generator)
   return Response(response=offense_json, status=200, mimetype='application/json')
  except Exception as e:
   log('Error ' + str(e))
   raise

def custom_html_generator(offense_json): 3 
    return ('<table><tbody>' +
            '<tr><td><strong>Offense ID</strong></td>
                 <td>' + str(offense_json['id']) + '</td></tr>' +
            '<tr><td><strong>Source IP</strong></td>
                 <td>' + offense_json['offense_source'] + '</td></tr>' +
            '<tr><td><strong>Severity</strong></td>
                 <td>' + str(offense_json['severity']) + '</td></tr>' +
            '</tbody></table>')
The following list describes the contents in the code snippet from the views.py scipt.
  1. The get_offense_json_html function that is imported from the app/qpylib/offense_qpylib.py library retrieves the details of the offense ID in JSON format.
  2. The get_offense function has an @app.route annotation that defines the endpoint's route. Its value is composed of the manifest's rest_endpoint field value /fragoffense, and the context information. In this case, the context information is the offense ID for the current offense on the Offense Summary page.
  3. The custom_html_generator function formats the offense JSON that was retrieved into an HTML table.