IBM Support

Using Named Services

How To


Summary

This tutorial will outline how to create four different apps, each using named services. The four apps will each utilise a different configuration of named service.

Steps

Prerequisites

Each of the four apps will require the following:

  • QRadar App SDK v2

Named Service with a Command as a Background Process

This app will serve a normal Flask app over port 5000, but use a named service as a background process to repeatedly update a file that is being served with a timestamp.

Create the Background Process App

Create a new folder for the app:

mkdir NamedServiceCommand && cd NamedServiceCommand

Use the QRadar App SDK to initialise the app code:

qapp create

Write the Background Process App Manifest

Open the manifest.json file to edit some values to make it more relevant to the app, making it look like this:

{
  "name": "NamedServiceCommand",
  "description": "An app serving a data that is generated by a named service running in the background",
  "version": "1.0",
  "image": "qradar-app-base:2.0.0",
  "areas": [
    {
      "id": "FlaskArea",
      "text": "Area Served from Flask",
      "description": "Area Serving File Generated by Named Service from Flask",
      "url": "index",
      "required_capabilities": []
    }
  ],
  "services": [
    {
      "command": "/bin/bash /opt/app-root/app/background.sh",
      "directory": "/",
      "name": "NamedServiceBackgroundCommand",
      "path": "/",
      "version": "1"
    }
  ],
  "uuid": "<your unique app UUID>"
}

This manifest defines some key properties:

  • A background named service called NamedServiceBackgroundCommand that runs a script /opt/app-root/app/background.sh; this script will run in the background.
  "services": [
    {
      "command": "/bin/bash /opt/app-root/app/background.sh",
      "directory": "/",
      "name": "NamedServiceBackgroundCommand",
      "path": "/",
      "version": "1"
    }
  ],
  • An area in the QRadar UI that serves a normal Flask endpoint; this Flask endpoint will read the output of the named service defined above and return it.
  "areas": [
    {
      "id": "FlaskArea",
      "text": "Area Served from Flask",
      "description": "Area Serving File Generated by Named Service from Flask",
      "url": "index",
      "required_capabilities": []
    }
  ],

Add Named Service Background Process Script

Create the script which will be the background named service, this is a simple bash script that will repeatedly update the /opt/app-root/store/background_output file with a message and timestamp; create the file app/background.sh.

#!/bin/bash

while true
do
    echo "Background named service last updated: $(date)" > /opt/app-root/store/background_output
    sleep 5
done

Update Flask Background Process Endpoints

Update the app HTTP endpoints by editing app/views.py:

from flask import Blueprint

# pylint: disable=invalid-name
viewsbp = Blueprint('viewsbp', __name__, url_prefix='/')

# A simple endpoint that returns the 'background_output' file that is managed by the background named service
@viewsbp.route('/')
def background_output_read():
    with open('/opt/app-root/store/background_output', 'r') as file:
        background_content = file.read()
        return background_content

This sets up a simple endpoint under the path / that will read the /opt/app-root/store/background_output file generated by the named service script defined above and returns it.

Background Process Conclusion

Following these steps results in a full QRadar app that has two parallel processes, Flask to serve HTTP endpoints, and a background script running that repeatedly updates a file that the endpoints serve.

Named Service with a Port Exposing Flask as a Named Service

This app will use a named service with a port to expose Flask, allowing the app's Flask endpoints to be called from different parts of QRadar; in this instance as a configuration page.

Create the Exposing Flask App

Create a new folder for the app:

mkdir NamedServicePort && cd NamedServicePort

Use the QRadar App SDK to initialise the app code:

qapp create

Write the Exposing Flask App Manifest

Open the manifest.json file to edit some values to make it more relevant to the app, making it look like this:

{
  "name": "NamedServicePort",
  "description": "An app that uses a named service to expose Flask as a named service",
  "version": "1.0",
  "image": "qradar-app-base:2.0.0",
  "configuration_pages": [
    {
      "text": "Flask Exposed through Named Service Config Page",
      "description": "Configuration page exposing Flask as a named service",
      "url": "/index",
      "named_service": "NamedServicePort",
      "required_capabilities":[]
    }
  ],
  "services": [
    {
      "port": 5000,
      "name": "NamedServicePort",
      "path": "/",
      "version": "1"
    }
  ],
  "uuid": "<your unique app UUID>"
}

This manifest defines some key properties:

  • A named service NamedServicePort exposes Flask, running on default port 5000, as a named service - allowing it to be queried from different parts of QRadar.
  "services": [
    {
      "port": 5000,
      "name": "NamedServicePort",
      "path": "/",
      "version": "1"
    }
  ],
  • A configuration page, which will show up on the 'Admin' section of QRadar, displaying the /index value queried from the NamedServicePort named service.
  "configuration_pages": [
    {
      "text": "Flask Exposed through Named Service Config Page",
      "description": "Configuration page exposing Flask as a named service",
      "url": "/index",
      "named_service": "NamedServicePort",
      "required_capabilities":[]
    }
  ],

Update Exposing Flask App Flask Endpoints

Update the app HTTP endpoints by editing app/views.py:

from flask import Blueprint

# pylint: disable=invalid-name
viewsbp = Blueprint('viewsbp', __name__, url_prefix='/')

# A simple endpoint that returns a string, to be called from a configuration page using a named service
@viewsbp.route('/index')
def index():
    return "This is returned from Flask running through a named service"

This sets up a simple Flask HTTP endpoint that returns a string when /index is queried.

Exposing Flask Conclusion

Following these steps results in a full QRadar app that exposes Flask as a named service, and uses a configuration page (which is visible on the 'Admin' section of the QRadar UI) to query the named service.

Named Service with a Command and a Port Replacing Flask

This app will replace Flask with a named service running on the default port (5000), this named service will instead use the built in Python HTTP server.

Create the Replacing Flask App

Create a new folder for the app:

mkdir NamedServiceCommandAndPort && cd NamedServiceCommandAndPort

Use the QRadar App SDK to initialise the app code:

qapp create

Write the Replacing Flask App Manifest

Open the manifest.json file to edit some values to make it more relevant to the app, making it look like this:

{
  "name": "NamedServiceCommandAndPort",
  "description": "An app serving using a named service running with a command and port",
  "version": "1.0",
  "image": "qradar-app-base:2.0.0",
  "load_flask": "false",
  "areas": [
    {
      "id": "NamedServiceCommandAndPortArea",
      "text": "Area Served from Named Service",
      "description": "Area Served from Named Service with Command and Port",
      "named_service": "NamedServiceCommandAndPort",
      "url": "index.html",
      "required_capabilities": []
    }
  ],
  "services": [
    {
      "command": "python3 -m http.server 5000",
      "directory": "/opt/app-root/app/named_service",
      "name": "NamedServiceCommandAndPort",
      "path": "/",
      "version": "1",
      "port": 5000
    }
  ],
  "uuid": "<your unique app UUID>"
}

This manifest defines some key properties:

  • The app does not load Flask, instead it uses a named service running on the default port 5000.
  "load_flask": "false",
  • A named service called NamedServiceWithCommand using the built in Python HTTP server to serve files out of the directory /opt/app-root/app/named_service over port 5000.
  "services": [
    {
      "command": "python3 -m http.server 5000",
      "directory": "/opt/app-root/app/named_service",
      "name": "NamedServiceWithCommand",
      "path": "/",
      "version": "1",
      "port": 5000
    }
  ],
  • An area in the QRadar UI that queries this named service for a file index.html.
  "areas": [
    {
      "id": "NamedServiceCommandAndPort",
      "text": "Area Served from Named Service",
      "description": "Area Served from Named Service with Command and Port",
      "url": "index.html",
      "required_capabilities": []
    }
  ],

Add Content to Serve to the Replacing Flask

Create the directory for holding the content to serve from the named service from the top-level directory of your app workspace:

mkdir -p app/named_service

Now create the index.html file that will be served by the named service and requested by the area defined in the manifest; create the file app/named_service/index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>Hello from Named Service With Command and Port</title>
  </head>
  <body>
      <h1>This page is being served from a named service</h1>
  </body>
</html>

Now create a debug file that will respond to QRadar App Framework healthchecks - this is a requirement of QRadar apps, this is the only way QRadar can determine if an app is up and running; a 200 OK response to the /debug path on the default port (5000). Create the file app/named_service/debug, this can be any minimal content - the only requirements are it must return 200 OK when queried and should be a small amount of data returned; for example:

File to return 200 to the /debug endpoint

Replacing Flask Conclusion

Following these steps results in a full QRadar app that uses the built in Python HTTP server running as a named service that presents an HTML webpage as a QRadar area.

Named Service with a Command, a Port, and Endpoints; Running in Parallel to Flask

This app will run Flask and a named service in Parallel. The named service will run using the Python built in HTTP server. The app will serve an area from Flask, and a configuration page from the named service.

Create the Parallel Flask Process App

Create a new folder for the app:

mkdir NamedServiceCommandPortEndpoints && cd NamedServiceCommandPortEndpoints

Use the QRadar App SDK to initialise the app code:

qapp create

Write the Parallel Flask Process App Manifest

Open the manifest.json file to edit some values to make it more relevant to the app, making it look like this:

{
  "name": "NamedServiceCommandPortEndpoints",
  "description": "An app that uses Flask and a Python webserver as a named service running in parallel",
  "version": "1.0",
  "image": "qradar-app-base:2.0.0",
  "areas": [
    {
      "id": "FlaskIndex",
      "text": "Area Served from Flask",
      "description": "Area Served from Flask",
      "url": "index",
      "required_capabilities": []
    }
  ],
  "configuration_pages": [
    {
      "text": "Configuration Page Served through Named Service",
      "description": "Configuration page served through named service",
      "url": "/index.html",
      "named_service": "NamedServiceCommandPortEndpoints",
      "required_capabilities":[]
    }
  ],
  "services": [
    {
      "command": "python3 -m http.server 5001",
      "directory": "/opt/app-root/app/named_service",
      "name": "NamedServiceCommandPortEndpoints",
      "path": "/",
      "version": "1",
      "port": 5001,
      "endpoints":  [
        {
          "name":"config_index",
          "path":"index.html",
          "http_method": "GET",
          "parameters": []
        }
      ]
    }
  ],
  "uuid": "<your unique app UUID>"
}

Add Content to Serve to the Parallel Flask Process App

Create the directory for holding the content to serve from the named service from the top-level directory of your app workspace

mkdir -p app/named_service

Now create the index.html file that will be served by the named service and requested by the configuration page defined in the manifest; create the file app/named_service/index.html:

<!DOCTYPE html>
<html>
  <head>
    <title>Hello from Named Service With Command, Port, and Endpoints</title>
  </head>
  <body>
      <h1>This page is being served from a named service</h1>
  </body>
</html>

Parallel Flask Process Conclusion

Following these steps results in a full QRadar app that uses both Flask and the built in Python HTTP server to return content for both an area and a configuration page.

Document Location

Worldwide

[{"Line of Business":{"code":"LOB24","label":"Security Software"},"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Product":{"code":"SSBQAC","label":"IBM Security QRadar SIEM"},"ARM Category":[{"code":"a8m0z000000cwt3AAA","label":"QRadar Apps"}],"ARM Case Number":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"All Version(s)"}]

Document Information

Modified date:
30 March 2021

UID

ibm16437485