resilient-circuits¶
Framework used to run IBM SOAR Apps and Integrations.
Commands¶
resilient-circuits
exposes the following commands:
run¶
Start up resilient-circuits in a local integration server environment.
Run resilient-circuits:
$ resilient-circuits run
Run resilient-circuits in DEBUG mode:
$ resilient-circuits run --loglevel=DEBUG
config¶
Manage configuration file app.config (integration server only). Default location is ~/.resilient/app.config
Create the app.config file in the default location:
$ resilient-circuits config -c
Update the app.config file with newly installed apps:
$ resilient-circuits config -u
Contains the class AppFunctionComponent
that gets generated using the codegen command in the resilient-sdk
Components¶
resilient-circuits
also provides the high level Python API which each app function is built off of.
- class AppFunctionComponent(*args, **kwargs)¶
Each package that has been generated with the
resilient-sdk codegen
command that contains a SOAR Function, anAppFunctionComponent
will be generated in the package’scomponents
directoryEach
AppFunctionComponent
, gets loaded into theresilient-circuits
framework and listens for messages on it’sMessage Destination
- __init__(opts, package_name, required_app_configs=[])¶
- Sets and exposes 4 properties:
self.PACKAGE_NAME: the name of this App, the parameter passed in
self.app_configs: a collections.namedtuple object of all associated configurations in the
app.config
file for this. App Configurations can be accessed like:base_url = self.app_configs.base_url
self.rc: an instantiation of
resilient_lib.RequestsCommon
which will have access to theexecute
method for external API callsself.LOG: access to a common
Logger
object. Can be used like:self.LOG.info("Starting '%s'", self.PACKAGE_NAME)
- Parameters:
opts (dict) – all configurations from the
app.config
filepackage_name (str) – the name of this App
required_app_configs ([str, str, ...]) – a list of required
app.config
configurations that are required to run this App
- Raises:
ValueError – if a
required_app_config
is not found inopts
- get_fn_msg()¶
Get the STOMP Message that has been sent from SOAR as a dict. The contents of the Message can include:
'function': { 'creator': '', 'description': '', 'display_name': 'mock_function', 'id': 3, 'name': 'mock_function', 'tags': [...], 'uuid': '', 'version': None, 'view_items': [...], ... }, 'groups': [], 'inputs': { 'mock_input_one': True, 'mock_input_two': 'abc', }, 'playbook_instance': None, 'principal': { 'display_name': '', 'id': 1, 'name': '', 'type': 'user' }, 'workflow': { 'actions': [...], 'description': '', 'name': '', 'object_type': { ... }, 'programmatic_name': '', 'tags': [...], 'uuid': '', 'workflow_id': 3 }, 'workflow_instance': { 'workflow_instance_id': 54 }
- Returns:
STOMP Message received from SOAR
- Return type:
dict
- static status_message(message)¶
Returns the message encapsulated in a
resilient_circuits.StatusMessage
objectUsage:
yield self.status_message("Finished running App Function: '{0}'".format(FN_NAME))
- Parameters:
message (str) – Message you want to send to Action Status
- Returns:
message encapsulated as
StatusMessage
- Return type:
resilient_circuits.StatusMessage
- ResilientComponent.rest_client(self)¶
Return a connected instance of the
resilient.SimpleClient
that can be used to access the IBM SOAR REST API.Note
An
AppFunctionComponent
inherits aResilientComponent
so will have access to this methodExample:
from resilient_circuits import AppFunctionComponent, FunctionResult, app_function PACKAGE_NAME = "fn_mock_app" FN_NAME = "mock_function" class FunctionComponent(AppFunctionComponent): def __init__(self, opts): super(FunctionComponent, self).__init__(opts, PACKAGE_NAME) @app_function(FN_NAME) def _app_function(self, fn_inputs): res_client = self.rest_client() inc = res_client.get("/incidents/{0}".format("1001")) inc_name = inc.get("name") results = { "inc": inc, "inc_name": inc_name } yield FunctionResult(results)
- Returns:
a connected instance of
resilient.SimpleClient
- Return type:
Decorators¶
- @app_function(*args, **kwargs)¶
Creates a new
@app_function
decorator.This decorator can be applied to methods of the
AppFunctionComponent
class.It marks the method as a handler for the events passed as arguments to the decorator.
Specify the function’s API name as parameter to the decorator. It only accepts 1
api_name
as an argument.The function handler will automatically be subscribed to the function’s
message destination
.
Helpers¶
- is_this_a_selftest(component)¶
Return
True
orFalse
if this instantiation ofresilient-circuits
is from selftest or not.- Parameters:
component (circuits.Component) – the current component that is calling this method (usually
self
)- Return type:
bool
Change Log¶
2024-07: version 51.0.2.2 * Update dependency version of setuptools version to 70.3.x to address CVE-2024-6345
2024-07: version 51.0.2.1
All IBM SOAR Python libraries now only officially support Python 3.9, 3.11, and 3.12. To continue using SOAR libraries on earlier versions of Python, use v52.0.2.0.974
Replace underlying stomp library (previously
stompest
) with modern librarystomp.py
Remove stomp configuration option
stomp_params
. This is no longer supported with the newstomp.py
libraryFix for secret substitution when value starts with “^” but is not intended to be substituted
2024-05: version 51.0.2.0
Added official support for Python 3.12
There is a known issue with running
resilient-circuits
as a service on Windows in Python 3.12. This is not a problem withresilient-circuits
, however, the development team will continue to monitor this for a time when Windows does support Python 3.12 services. Until then, please use Python 3.11 or 3.9 on Windows for integration servers
2024-04: version 51.0.1.1
Updated selftest to better handle connection issues when running in App Host
Modified
stomp_prefetch_limit
configuration option to default to the same value asnum_workers
. The prefetch limit can still be manually adjusted by changingstomp_prefetch_limit
in the[resilient]
section of app.config if you desire the prefetch and workers to have different valuesInbound app decorator now expects headers as the second parameter for the decorated function. This is intended for better debugging with more inbound message information passed to the handler
2024-02: version 51.0.1.0
All SOAR Python libraries now officially support Python 3.11
Selftest now outputs
pip
environment details to better debug failing tests by quickly seeing the dependency versionsresilient_circuits.rest_helper.get_resilient_client
now uses a cache rather than a global variable to store previously fetched clients. This is an improvement for threaded applications using this logic to store multiple client objects for different instances
2023-11: version 51.0.0.0
Added support for new SOAR v.r.m.f version scheme. If running an app on
resilient-circuits<51.0.0.0
, the incorrect version of the SOAR server may be displayed if connecting to a SOAR server with version greater than or equal to 51.x. Please consider upgradingresilient-circuits
to the latest version as soon as you can. A gentle reminder that SOAR python libraries versioning is independent of SOAR server versions and any version of circuits works with any version of SOAR (i.e.resilient-circuits==v51.0.0.0
will work fine with SOAR v48.0.0). It is always recommended that you use the latest version of all SOAR Python LibrariesRemoved obfuscation of “id” in logs and made general improvements of log obfuscation to better target sensitive information while leaving important information in the logs
2023-10: version 50.1
Allow for
.
character in message queue names and improved logging around queues not found on startupMerged external PR to improve support for multiple circuits services running in Windows
2023-08: version 50.0
Added support for app secrets in function inputs. Use the syntax similar to using app secrets in app.config by referencing app secrets in text within a function input. Example:
inputs.fn_my_fn_input_1 = "$SECRET_FROM_APP_HOST_PROTECTED_SECRETS" inputs.fn_my_fn_input_2 = "Here we can insert our ${SECRET_FROM_APP_HOST} in the middle of the string" inputs.fn_my_fn_input_3 = "^SECRET_FROM_PAM"
2023-07: version 49.1
No major changes. Just bumping build number to coincide with other builds
2023-05: version 49.0
Improved logging on restarts
Improved obfuscation of sensitive information from app.config in logs
Added ability to disable persistent sessions for
resilient-lib.RequestsCommon
in app functions using new optionalrc_use_persistent_sessions
configuration parameterAdded
resilient-app-config-plugins
as a new package to manage third party credentials within SOAR apps
2023-04: version 48.1
Better log handling for errors upon restart
Added new configs for log rotation.
log_max_bytes
sets the maximum bytes per log file; defaults to10000000
.log_backup_count
sets the maximum number of log files to keep as backups while files rotate; defaults to10
Improved log filtering for sensitive values
2023-02: version 48.0
Include
threadName
in the app logsDisplay SOAR server version in startup logs. Note: for CP4S this displays the underlying SOAR version, not the platform version
Updated project to use
pyproject.toml
andsetup.cfg
metadata files. Build backend continues to usesetuptools
. Instead of directly invoking setup.py to get a sdist or wheel, usebuild
as a build frontend:pip install build python -m build
2022-12: version 47.1
No major changes. Just bumping build number to coincide with other builds
2022-11: version 47.0
Updated default
num_workers
value to 25 if not set and default value in template app.config file to 50
2022-08: version 46.0
The
FunctionResult
in anAppFunctionComponent
now supports acustom_results
kwarg. If set toTrue
the dictionary of results sent to SOAR will be exactly as passed and not contain our default payload. We do not recommend this however in some cases it may be necessaryEnhanced the
resilient_circuits.is_this_a_selftest()
method to check if a Component has been instantiated in a resilient-circuits instance runningselftest
. Example:from resilient_circuits.helpers import is_this_a_selftest if is_this_a_selftest(self): # Do nothing...
Added a new configuration setting to app.config, called
heartbeat_timeout_threshold
. It is a value in seconds between the currentHeartbeatTimeout
event and the firstHeartbeatTimeout
event. If the time is greater than theheartbeat_timeout_threshold
, the resilient-circuits process stops.
2022-07: version 45.1
Bug fix to avoid
@app_function
Components firing on all channels leading to Functions being invoked multiple times
2022-05: version 45.0
Added new config
trap_exception
and if set toTrue
a Function’s exception will be ignored with the error sent as a Status Message and a default payload returned like below, allowing the Workflow or Playbook to continue{ "success": False, "reason": "Error message" }
Added a custom header for all requests from
resilient-circuits
that will include the current version of the library:Resilient-Circuits-Version: 45.0.0
Better handling of errors if an app’s
selftest
is unimplemented
2022-04: version 44.1
Move Jinja template management functions to
resilient-lib
while keeping backward compatibility here
2022-02: version 44.0
Ensure
tests/
is not included in packaged codeBump
Jinja2
to~=3.0
for Python>=3.6
Officially support
Python 3.9
2022-01: version 43.1
Bug fix for
selftest
2021-11: version 43.0
Formatted Sphinx documentation and hosted it at https://ibm.biz/soar-python-docs
2021-11: version 42.3
No major changes. Just bumping build number to coincide with other builds
2021-10: version 42.2
No major changes. Just bumping build number to coincide with other builds
2021-08: version 42.1
No major changes. Just bumping build number to coincide with other builds
2021-08: version 42.0
Added support for
HTTP_PROXY
,HTTPS_PROXY
andNO_PROXY
environmental variables. See the App Host Deployment Guide for details.Enhancement to
selftest
to also check connection back to SOAR platform.Added
selftest_timeout
to app.config file. It sets the value in seconds forselftest
to wait for a response from the SOAR platform.Bug fixes.
2021-06: version 41.1
Increase
num_workers
limit to 500
2021-05: version 41.0
Deprecate
test
commandRemove deprecated commands
clone
,extract
andextract
Increase
num_workers
limit to 100Added dependency of
resilient-lib
Bug fixes
Handle new app_function decorator
2021-03: version 40.2
Bug fix for to use
setuptools_scm < 6.0.0
for Python 2.7 environments
2021-03: version 40.1
No major changes. Just bumping build number to coincide with other builds
2021-02: version 40.0
Remove need for calling
/message_destinations
endpointAdded
--print-env
flag toselftest
command to print the environment when the test runsPython version and installed packages printed out to log at start of
resilient-circuits run
[integrations]
section added by default when app.config file first created withresilient-circuits config -c
Bug fixes
2020-12-08: version 39.0
resilient-circuits
now only loads the functions that are pip installed and/or are in the components directoryAdded
num_workers
as an app config which specifies how many functions you can run in parallel within the range 1-50 inclusive. It defaults to 10.selftest
now has an exit code of 1 if it failsexits circuits on
Not connected event
2020-08-05: version 38.0
Exposed timeouts and tuning parameters to API and STOMP timeouts
2020-07-15: version 37.2
Sorted output for
list
command.Bug fixes.
2020-04-15: version 37
Deprecated
codegen
andextract
command-line arguments. Seeresilient-sdk
for moved functionality.
2020-04-15: version 36.2.dev
Deprecated
codegen
andextract
command-line arguments. Seeresilient-sdk
for moved functionality.
2020-01-16: version 35.0.195
Moved
ImportDefinition
toresilient
packageFixed handling of
APP_CONFIG_FILE
in different contextsChanged
resilient
dependency to be>=35
Fixed
resilient-circuits run -r
Fixed dependency issue for
watchdog
2019-10-07 version 34.0.194
Updated exception handling. Introduced
BaseFunctionError
class, ability to hide trace, and include messages.Fix cafile=false throwing AttributeError
Fix a bug when Python component’s
package_name == function_name
2019-08-02: version 33.0.189
Added support for API key and API key secret, now able to authenticate using API keys instead of email/password.
Other minor bug fixes.
2019-07-03: version 32.0.186
Fix for deprecated log warnings.
Other minor bug fixes.
2019-04-12: version 32.0.140
Fix for exposed Resilient passwords in
resilient-circuits
log when run in DEBUG mode.codegen
createssetup.py
files which will programmatically compute function component entry points.Added WorkflowStatus class.
Running
codegen
,codegen --reload
, andextract
now automatically creates export files in Resilient to run against. Manually export no longer needed.extract
will now extract all data associated with playbooks including Tasks, Scripts, and custom Artifact Types.Support for activemq hosted externally (ISC).
Improvements to
resilient-lib
.Other minor bug fixes/improvements.
2019-03-06: version 32.0.126
Removed
selftest
from function templateImprovements to
resilient-lib
2019-01-15: version 32.0
Fixed an issue with
resilient-circuits extract
2018-12-05: version 31.0
Add
resilient-circuits selftest
command to callselftest
functions for every package and prints their return stateAdd
resilient-circuits clone
Clone Resilient workflowsAdd
resilient-circuits codegen --reload
command to reload existing packageAdd
resilient-circuits extract
command to extract customization data into a single fileAdded support for specifying lists of packages to run
config/customize/selftest
againstAdded
extract
improvementsJinja template improvements
Bug Fixes
2018-04-15: version 30.0
Add
@function
decorator to implement workflow functionsAdd
resilient-circuits test
command to replace res-action-testAdd
resilient-circuits codegen
command to generate boilerplate functions and installable packagesAdd
resilient-circuits customize
command to import customizations from installed packagesFix an issue with keyring values outside the [resilient] config section
Fix various issues with
pytest-resilient-circuits
mocks and fixturesUpdate action message log format for greater readability
Update
resilient-circuits list
to show packages with no componentsAdd
-v
flag toresilient-circuits list
2018-02-22: version 29.1.0
Fix an issue with performance receiving STOMP messages
2017-12-12: version 29.0.1
No major changes. Just bumping build number to coincide with other builds
2017-12-01: version 29.0.0
New package versions: Published under the MIT open-source license.
New package versions: Published to pypi.
change default JINJA autoescape for safety
2017-09-01: version 28.2.1
change license to MIT
Add ‘docs’ for autogenerated package documentation
2017-08-24: version 28.1.
fix a problem with python3 handling unicode surrogate pairs (e.g. emoji) in action messages
add ‘idna’ and ‘punycode’ JINJA filters for domain encoding
add ‘–config-file’ commandline argument
fix various performance and reliability issues
2017-06-22: version 28.0.33
No major changes. Just bumping build number to coincide with other builds
2017-06-14: version 28.0.30
Change the STOMP protocol implementation from ‘stomp.py’ to ‘stompest’ library, with a significant refactoring, for better reliability and maintainability.
Add support for STOMP connections via proxy server.
Add a dependency on ‘stompest’ and ‘pysocks’ packages
Remove old ‘stomp.py’-based examples
Name unnamed actions, e.g. those initiated from v28 workflow, as ‘_unnamed_’
Defer subscribing to queues until all components have loaded
Fix a problem with international characters in ‘get_action_field_label()’
Fix a problem with international characters in status messages and exceptions
Change to the ‘app_restartable’ functionality to remove a memory leak and streamline. Instead of fully unloading and reloading components on configuration file changes, components are instead sent a ‘reload’ event.
Update the file_lookup example to handle the reload event
2017-04-27: version 27.1.22
Remove ‘dist’, instead releases are available on https://github.com/Co3Systems/co3-api/releases
Build numbering to track the ‘co3’ module; depend where version is >= major.minor
Config entry ‘stomp_cafile’ to support using different TLS certificates for STOMP and REST
Bugfix in ‘app_restartable’ configuration file handling
2017-04-21: version 27.1.13
Various updates for reliability
New support for packaged installable application components
New ‘resilient-circuits’ utility executable to configure and run applications
Make ‘components’ directory optional
Updated configuration file locations ($APP_CONFIG_FILE or ./app.config or ~/.resilient/app.config)
Log the servername at startup
2017-02-17: version 27.0.0
Licensing change to “IBM Resilient”
Add documentation for reading configuration values from keystore with ‘key=^VALUE’ syntax
Add an option for reading configuration values from the environment with ‘key=$VALUE’ syntax
Add ‘@debounce()’ decorator for event handler functions
Add ‘–noload’ option to skip loading specific components
Load components in a deterministic order (alphabetically)
Better handle connecting to Resilient without Action Module enabled
Better consistency with REST API in TLS certificate verification
2016-08-10: version 26.0.3
Add requirements.txt for easier offline downloading of Python dependencies
2016-08-10: version 26.0.2
Fix issue when unsubscribing from STOMP queues
2016-08-01: version 26.0.1
Allow override of password prompting
Allow blank config values
Fix an issue with ‘app-restartable’ updating too often
Fix an issue with events for non-string channel ids
Fix an issue with loading some action components