GUI application framework fundamentals
QRadar® GUI application framework apps are stand-alone web applications that run on the Flask micro-framework, and are served from the Flask web server.
Installation overview
Every app runs in its own unique Flask server. Each Flask server, in turn, runs within a secure Linux® container. Docker is the implementation stack for the secure containment of the Flask app codebase.
Each app is installed by using the RESTful API endpoints. The installation endpoint handles these tasks:
- Validates the manifest of the app.
- Automatically creates a Docker image (asynchronous) with the app code that is bundled within it.
- Registers the app (asynchronous) with QRadar to enable web traffic proxy and the HTTP request/response lifecycle from QRadar to the app.
- Automatically runs a Docker container from the Docker image (asynchronous), which is bound to a data-only secondary container that is used for persistent storage.
QRadar RESTful API endpoints
The key interface between lifecycle management of an app, during both its creation and running phases, is the QRadar GUI App Framework REST API endpoints.
The following table describes the QRadar RESTful API endpoints.
Endpoint | Parameters | Description |
---|---|---|
GET /gui_app_framework/application_creation_task | Application ID | Retrieves a list of status details for all asynchronous requests to create apps. |
GET /gui_app_framework/application_creation_task/{application_id} | Application ID | Retrieves a list of status details of an asynchronous request to create apps. |
POST /gui_app_framework/application_creation_task | Application (.zip) bundle file | Creates an app within the application framework, and registers it with QRadar. The app is created asynchronously. A reference to the application_id is returned and must be used in subsequent API calls to determine the status of the app installation. |
POST /gui_app_framework/application_creation_task/{application_id} | Application ID, cancel status | Updates a new app installation within the application framework The application_id and a status parameters are required. |
GET /gui_app_framework/applications | Retrieves a list of apps that are installed on the QRadar console, and their manifest JSON structures and status. | |
GET /gui_app_framework/applications/{application_id} | Application ID | Retrieves a specific app that is installed on the console and its manifest JSON structure and status. |
POST /gui_app_framework/applications/{application_id} | Application ID, start/stop status | Updates an app. Starts or stops an app by setting status to RUNNING or STOPPED respectively. |
PUT /gui_app_framework/applications/{application_id} | Application ID | Upgrade an application. |
DELETE /gui_app_framework/applications/{application_id} | Application ID | Deletes an application. |
GET /gui_app_framework/named_services | Retrieves a list of all named services registered with the Application Framework. | |
GET /gui_app_framework/named_services/{uuid} | uuid | Retrieves a named service registered with the Application Framework by using the supplied uuid. |
Python
The main web language that is used to author an app is Python, and the Flask framework is integrated and available for use by the app.For more information, go to the Python website (https://www.python.org/doc/).
Flask
Flask is a micro web application framework that is written in Python.
Flask is the web server from which the app-coded endpoints are served. You use Python functions to deliver use cases. You can use route annotations for each Python method in the Flask application. After the Flask web server starts, HTTP/HTTPS-bound requests are serviced by Flask for that route, and the Python functions are run.
Each Flask server that is run from within the Docker container uses port 5000. Outwardly from the container, Docker maps that internal port 5000 to the next free port from the 32768-60999 ephemeral range. During the registration phase, this outward mapped port is stored by QRadar so that web requests for an app, through QRadar are proxied to the correct container.
The following code is a sample Python route:
@app.route('/')
def hello_world():
return 'Hello World!'
In a standalone Flask web server, a web request through a browser to
http://localhost:5000
returns: Hello World!
The following table outlines the specific version of Flask, and its dependencies:
Packages | Version | Description |
---|---|---|
Flask | 0.10.1 | Microframework, or micro web application framework |
itsdangerous | 0.24 | Utility package for signing and encrypting data |
jinja2 | 2.7.3 | Template engine for python |
markupsafe | 0.23 | Unicode escape library used alongside Jinja2 |
Werkzeug | 0.96 | WSGI (Web Server Gateway Interface) utility library for Python |
For more information, see the Flask website (http://flask.pocoo.org/).
Jinja2
Jinja2 is a Python library that enables you to create templates for various output formats from a core template text file. HTML is the format that is used for QRadar apps. Jinja2 has a rich API, and large array of syntactic directives (statements, expressions, variables, tags) that you use to dynamically inject content into the template file.
Flask's in-built render_template()
method is the easiest way to inject data from
a Python method, served by the route, into a Jinja2 HTML template, as shown in the following
example.
@app.route('/')
def hello_world():
return render_template('hello.html', title='QRadar')
The template hello.html contains the following code:
<!doctype html>
<title>Hello from Flask</title>
<h1>Hello {{ title }}!</h1>
The following HTML output is produced:
<!doctype html>
<title>Hello from Flask</title>
<h1>Hello QRadar!</h1>
For more information, see the Jinja2 website (http://jinja.pocoo.org/docs/dev/).
HTTP request response lifecycle
When an app is successfully installed, requests to the app are proxied only by using an established connection to QRadar. The app cannot be directly accessed by using direct URL requests or any other method.
Apps can establish a secure authenticated and authorized session to QRadar. Any authorization tokens that are created to verify that the integrity of session can be reused. The app obtains all the capabilities, security, and authenticity facets of QRadar. The app can use the user session state to get access to all of QRadar RESTful API endpoints to pull or push data to or from the QRadar system.
Containerized apps and the network
With the GUI Application Framework, traffic flows from container to container, from container to host on its public IP address (not localhost), and from containers to the outside world.
When each app is passed as an archive (.zip file) of source code to the QRadar endpoints, QRadar builds the initial image specific to your app codebase. Each image runs as an individual container. As the container is run or started, QRadar maps the internal flask server port (5000) to an external ephemeral port. This external ephemeral port is registered to QRadar so that proxied requests to your app code are routed to the correct container.
/debug
endpoints
All apps must include a /debug
endpoint or route that runs locally on port 5000.
If you use the default flask framework, this endpoint is automatically included in your root
_init_.py file. This endpoint is used to ensure live apps are active and
reachable.
If you disable the default flask to allow the app to use its own web server, you must include a
/debug
endpoint on port 5000. If you do not include the endpoint, your app will
restart once per minute, as a result of QRadar being unable to receive a
response from the app.