splunk-soar-sdk 1.4.1__tar.gz → 1.5.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/.pre-commit-config.yaml +7 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/PKG-INFO +1 -1
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/api_reference.rst +26 -13
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/app_structure/index.rst +1 -1
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/app_structure/pre-commit-config.yaml.rst +1 -1
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/app_structure/src_app.rst +107 -21
- splunk_soar_sdk-1.5.1/docs/cli_reference.rst +51 -0
- splunk_soar_sdk-1.5.1/docs/getting_started/defining_asset.rst +32 -0
- splunk_soar_sdk-1.5.1/docs/getting_started/first_action.rst +119 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/getting_started/index.rst +3 -0
- splunk_soar_sdk-1.5.1/docs/getting_started/init_app.rst +118 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/getting_started/installation.rst +1 -1
- splunk_soar_sdk-1.5.1/docs/getting_started/testing_and_building.rst +47 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/index.rst +3 -3
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/pyproject.toml +4 -4
- splunk_soar_sdk-1.5.1/release_notes.txt +23 -0
- splunk_soar_sdk-1.5.1/release_version.txt +1 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/abstract.py +1 -4
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/actions_manager.py +3 -5
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/app.py +96 -13
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/app_cli_runner.py +3 -8
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/manifests/processors.py +2 -2
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/compat.py +2 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/meta/app.py +1 -1
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/params.py +1 -3
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/shims/phantom/action_result.py +3 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/views/template_filters.py +5 -2
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/manifests/test_processors.py +20 -17
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/test_package_cli.py +1 -1
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/conftest.py +0 -7
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/app.json +105 -45
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/src/actions/async_action.py +6 -3
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/src/actions/reverse_string.py +1 -3
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/src/app.py +6 -12
- {splunk_soar_sdk-1.4.1/tests/example_app_with_webhook → splunk_soar_sdk-1.5.1/tests/example_app}/uv.lock +335 -278
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/stubs.py +1 -1
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_actions_manager.py +42 -25
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_app_action.py +73 -13
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_app_runner.py +79 -99
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_generic_action.py +24 -16
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_logging.py +72 -59
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_on_poll.py +73 -61
- splunk_soar_sdk-1.5.1/tests/test_template_filters.py +207 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_test_connectivity.py +18 -12
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/uv.lock +1 -1
- splunk_soar_sdk-1.4.1/docs/cli_reference.rst +0 -11
- splunk_soar_sdk-1.4.1/docs/getting_started/init_app.rst +0 -245
- splunk_soar_sdk-1.4.1/release_notes.txt +0 -31
- splunk_soar_sdk-1.4.1/release_version.txt +0 -1
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/.github/ISSUE_TEMPLATE/bug.md +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/.github/pull_request_template.md +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/.github/utils/github.js +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/.github/utils/update_version.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/.github/workflows/code_quality.yml +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/.github/workflows/commit_hygiene.yml +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/.github/workflows/generate_docs.yml +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/.github/workflows/semantic_release.yml +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/.gitignore +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/.releaserc +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/LICENSE +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/README.md +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/commitlint.config.js +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/app_structure/pyproject.toml.rst +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/changelog.rst +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/conf.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/custom_views/index.rst +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/custom_views/reusable_components.md +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/custom_views/templates.md +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/custom_views/view_handlers.md +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/action_results.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/apis/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/apis/artifact.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/apis/container.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/apis/utils.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/apis/vault.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/app_client.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/app_templates/basic_app/.gitignore +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/app_templates/basic_app/.pre-commit-config.yaml +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/app_templates/basic_app/logo.svg +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/app_templates/basic_app/logo_dark.svg +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/app_templates/basic_app/src/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/app_templates/basic_app/uv.lock +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/asset.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/async_utils.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/cli.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/init/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/init/cli.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/manifests/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/manifests/cli.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/manifests/deserializers.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/manifests/serializers.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/package/cli.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/package/utils.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/path_utils.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/cli/utils.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/code_renderers/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/code_renderers/action_renderer.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/code_renderers/app_renderer.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/code_renderers/asset_renderer.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/code_renderers/renderer.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/code_renderers/templates/pyproject.toml.jinja +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/code_renderers/toml_renderer.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/colors.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/crypto.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/decorators/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/decorators/action.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/decorators/generic_action.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/decorators/on_poll.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/decorators/test_connectivity.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/decorators/view_handler.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/decorators/webhook.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/exceptions.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/input_spec.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/logging.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/meta/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/meta/actions.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/meta/adapters.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/meta/datatypes.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/meta/dependencies.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/meta/webhooks.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/models/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/models/artifact.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/models/container.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/models/vault_attachment.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/models/view.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/paths.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/py.typed +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/shims/phantom/app.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/shims/phantom/base_connector.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/shims/phantom/connector_result.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/shims/phantom/consts.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/shims/phantom/encryption_helper.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/shims/phantom/install_info.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/shims/phantom/json_keys.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/shims/phantom/ph_ipc.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/shims/phantom/vault.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/shims/phantom_common/app_interface/app_interface.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/shims/phantom_common/encryption/encryption_manager_factory.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/templates/base/base_template.html +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/templates/base/error.html +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/templates/base/header.html +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/templates/base/logo_header.html +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/templates/components/pie_chart.html +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/templates/widgets/widget_resize_snippet.html +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/templates/widgets/widget_template.html +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/types.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/views/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/views/component_registry.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/views/components/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/views/components/pie_chart.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/views/template_renderer.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/views/view_parser.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/webhooks/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/webhooks/models.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/src/soar_sdk/webhooks/routing.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/test.png +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/test.txt +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/datapath_parse.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/manifests/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/test_assets/converted_app/actions.py.txt +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/test_cli.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/test_convert_cli.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/test_deserializers.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/test_init_cli.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/test_manifests_cli.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/test_serializers.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/cli/test_utils.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/code_renderers/test_action_renderer.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/example_asset.json +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/logo.svg +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/logo_dark.svg +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/pyproject.toml +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/src/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/src/actions/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/src/actions/generate_category.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/src/ignoreme.txt +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app/templates/reverse_string.html +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app_with_webhook/app.json +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app_with_webhook/logo.svg +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app_with_webhook/logo_dark.svg +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app_with_webhook/pyproject.toml +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app_with_webhook/src/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/example_app_with_webhook/src/app.py +0 -0
- {splunk_soar_sdk-1.4.1/tests/example_app → splunk_soar_sdk-1.5.1/tests/example_app_with_webhook}/uv.lock +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/interfaces/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/interfaces/test_artifact_interface.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/interfaces/test_container_interface.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/interfaces/test_vault_interface.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/meta/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/meta/test_actions.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/meta/test_adapters.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/meta/test_datatypes.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/meta/test_dependencies.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/meta/test_webhooks.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/mocks/__init__.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/mocks/dynamic_mocks.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/mocks/importable_action.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_action_results.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_app.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_app_action_params.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_app_action_results.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_app_client.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_asset.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_assets/splunk-sdk-2.1.0.tar.gz +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_async_integration.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_async_utils.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_code_renderers.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_compat.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_container.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_custom_views.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_encryption.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_params.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_template_renderer.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/test_view_parser.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/webhooks/test_models.py +0 -0
- {splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/tests/webhooks/test_routing.py +0 -0
|
@@ -34,6 +34,13 @@ repos:
|
|
|
34
34
|
additional_dependencies: [tomli]
|
|
35
35
|
verbose: true
|
|
36
36
|
|
|
37
|
+
- repo: https://github.com/codespell-project/codespell
|
|
38
|
+
rev: v2.4.1
|
|
39
|
+
hooks:
|
|
40
|
+
- id: codespell
|
|
41
|
+
additional_dependencies:
|
|
42
|
+
- tomli
|
|
43
|
+
|
|
37
44
|
- repo: local
|
|
38
45
|
hooks:
|
|
39
46
|
- id: uv-lock
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: splunk-soar-sdk
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.1
|
|
4
4
|
Summary: The official framework for developing and testing Splunk SOAR Apps
|
|
5
5
|
Project-URL: Homepage, https://github.com/phantomcyber/splunk-soar-sdk
|
|
6
6
|
Project-URL: Documentation, https://github.com/phantomcyber/splunk-soar-sdk
|
|
@@ -5,7 +5,7 @@ API Reference
|
|
|
5
5
|
|
|
6
6
|
This section documents the public API of the Splunk SOAR SDK.
|
|
7
7
|
|
|
8
|
-
Jump to a
|
|
8
|
+
Jump to a Section:
|
|
9
9
|
------------------
|
|
10
10
|
|
|
11
11
|
- :ref:`api_ref_core_label`
|
|
@@ -13,6 +13,7 @@ Jump to a section:
|
|
|
13
13
|
- :ref:`asset-configuration-label`
|
|
14
14
|
- :ref:`action-param-label`
|
|
15
15
|
- :ref:`action-output-label`
|
|
16
|
+
- :ref:`soar-client-label`
|
|
16
17
|
- :ref:`api_ref_apis_label`
|
|
17
18
|
- :ref:`api_ref_data_models_label`
|
|
18
19
|
- :ref:`api_ref_logging_label`
|
|
@@ -64,7 +65,7 @@ BaseAsset
|
|
|
64
65
|
Action Parameters
|
|
65
66
|
~~~~~~~~~~~~~~~~~
|
|
66
67
|
|
|
67
|
-
Action parameters are defined in Pydantic models, which extend the
|
|
68
|
+
Action parameters are defined in Pydantic models, which extend the :class:`soar_sdk.params.Params` class.
|
|
68
69
|
At their most basic, parameters can have a simple data type such as ``str`` or ``int``.
|
|
69
70
|
|
|
70
71
|
.. code-block:: python
|
|
@@ -81,10 +82,10 @@ At their most basic, parameters can have a simple data type such as ``str`` or `
|
|
|
81
82
|
uid: int
|
|
82
83
|
|
|
83
84
|
|
|
84
|
-
Adding
|
|
85
|
+
Adding Extra Metadata
|
|
85
86
|
^^^^^^^^^^^^^^^^^^^^^
|
|
86
87
|
|
|
87
|
-
You can use the
|
|
88
|
+
You can use the :func:`~soar_sdk.params.Param` function to add extra information to a parameter type.
|
|
88
89
|
For example, let's give the ``uid`` field a Common Event Format (CEF) type and make it optional.
|
|
89
90
|
|
|
90
91
|
.. code-block:: python
|
|
@@ -100,20 +101,21 @@ For example, let's give the ``uid`` field a Common Event Format (CEF) type and m
|
|
|
100
101
|
is_admin: bool
|
|
101
102
|
uid: int = Param(required=False, cef_types=["user id"])
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
Defining Parameters
|
|
105
|
+
^^^^^^^^^^^^^^^^^^^
|
|
104
106
|
|
|
105
107
|
.. autoclass:: soar_sdk.params.Params
|
|
106
108
|
|
|
107
109
|
.. autofunction:: soar_sdk.params.Param
|
|
108
110
|
|
|
109
|
-
Parameters
|
|
110
|
-
|
|
111
|
+
Parameters For ``on poll``
|
|
112
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
111
113
|
On poll functions require a specific parameter class called `OnPollParams`. YYou should use this class as-is, instead of overriding it.
|
|
112
114
|
|
|
113
115
|
.. autoclass:: soar_sdk.params.OnPollParams
|
|
114
116
|
|
|
115
|
-
Parameters for
|
|
116
|
-
|
|
117
|
+
Parameters for the Generic Action
|
|
118
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
117
119
|
Generic action functions require a specific parameter class called `GenericActionParams`. You should use this class as-is, instead of overriding it.
|
|
118
120
|
|
|
119
121
|
.. autoclass:: soar_sdk.params.GenericActionParams
|
|
@@ -124,9 +126,9 @@ Generic action functions require a specific parameter class called `GenericActio
|
|
|
124
126
|
Action Outputs
|
|
125
127
|
~~~~~~~~~~~~~~
|
|
126
128
|
|
|
127
|
-
Action outputs are defined in Pydantic models, which extend the
|
|
129
|
+
Action outputs are defined in Pydantic models, which extend the :class:`~soar_sdk.action_results.ActionOutput` class.
|
|
128
130
|
|
|
129
|
-
Much like parameters, outputs can have simple data types such as ``str`` or ``int``, or be annotated with the
|
|
131
|
+
Much like parameters, outputs can have simple data types such as ``str`` or ``int``, or be annotated with the :func:`~soar_sdk.action_results.OutputField` function to add extra metadata.
|
|
130
132
|
|
|
131
133
|
.. code-block:: python
|
|
132
134
|
|
|
@@ -154,7 +156,7 @@ Output models can be nested, allowing you to create complex data structures:
|
|
|
154
156
|
class ListUsersOutput(ActionOutput):
|
|
155
157
|
users: list[UserDetails]
|
|
156
158
|
|
|
157
|
-
You can add summary data and a result message to your action, by calling
|
|
159
|
+
You can add summary data and a result message to your action, by calling :func:`soar_sdk.abstract.SOARClient.set_message` and :func:`soar_sdk.abstract.SOARClient.set_summary`. Summary objects are also subclasses of :class:`~soar_sdk.action_results.ActionOutput`, and you must register them in your action decorator:
|
|
158
160
|
|
|
159
161
|
.. code-block:: python
|
|
160
162
|
|
|
@@ -174,7 +176,8 @@ You can add summary data and a result message to your action, by calling `client
|
|
|
174
176
|
return ListUsersOutput(users=users)
|
|
175
177
|
|
|
176
178
|
|
|
177
|
-
|
|
179
|
+
Defining Action Outputs
|
|
180
|
+
^^^^^^^^^^^^^^^^^^^^^^^
|
|
178
181
|
|
|
179
182
|
.. autoclass:: soar_sdk.action_results.ActionOutput
|
|
180
183
|
|
|
@@ -186,6 +189,16 @@ For generic action functions we have provided a convenience class called `Generi
|
|
|
186
189
|
|
|
187
190
|
.. autoclass:: soar_sdk.action_results.GenericActionOutput
|
|
188
191
|
|
|
192
|
+
.. _soar-client-label:
|
|
193
|
+
|
|
194
|
+
SOARClient
|
|
195
|
+
~~~~~~~~~~~
|
|
196
|
+
|
|
197
|
+
The ``SOARClient`` class is an app's gateway to the Splunk SOAR platform APIs. It provides methods for creating and manipulating platform objects such as containers, artifacts, and vault items.
|
|
198
|
+
|
|
199
|
+
.. autoclass:: soar_sdk.abstract.SOARClient
|
|
200
|
+
:show-inheritance:
|
|
201
|
+
|
|
189
202
|
.. _api_ref_apis_label:
|
|
190
203
|
|
|
191
204
|
APIs
|
{splunk_soar_sdk-1.4.1 → splunk_soar_sdk-1.5.1}/docs/app_structure/pre-commit-config.yaml.rst
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
.. _app-structure-pre-commit:
|
|
2
2
|
|
|
3
3
|
``.pre-commit-config.yaml``
|
|
4
|
-
|
|
4
|
+
===========================
|
|
5
5
|
|
|
6
6
|
This file is the official configuration file for the `pre-commit <https://pre-commit.com>`_ tool. It adds some automation to
|
|
7
7
|
the process of committing changes when developing the app, and is a required file for all app repos in the official Splunk SOAR app Github organization. ``pre-commit`` is a framework for managing and maintaining multi-language pre-commit hooks. It helps ensure that code meets certain standards before it is committed to a repository, such as formatting, linting, and static security checks.
|
|
@@ -19,14 +19,14 @@ Here's an example ``app.py`` file which uses a wide variety of the features avai
|
|
|
19
19
|
:language: python
|
|
20
20
|
:linenos:
|
|
21
21
|
|
|
22
|
-
Components of the ``app.py``
|
|
22
|
+
Components of the ``app.py`` File
|
|
23
23
|
---------------------------------
|
|
24
24
|
|
|
25
25
|
Let's dive deeper into each part of the ``app.py`` file above:
|
|
26
26
|
|
|
27
27
|
.. _app-structure-logger-init:
|
|
28
28
|
|
|
29
|
-
Logger
|
|
29
|
+
Logger Initialization
|
|
30
30
|
~~~~~~~~~~~~~~~~~~~~~
|
|
31
31
|
|
|
32
32
|
.. literalinclude:: ../../tests/example_app/src/app.py
|
|
@@ -47,7 +47,7 @@ When running locally via the CLI, all log messages are printed to the console, i
|
|
|
47
47
|
|
|
48
48
|
.. _app-structure-asset-def:
|
|
49
49
|
|
|
50
|
-
Asset
|
|
50
|
+
Asset Definition
|
|
51
51
|
~~~~~~~~~~~~~~~~
|
|
52
52
|
|
|
53
53
|
.. literalinclude:: ../../tests/example_app/src/app.py
|
|
@@ -60,7 +60,7 @@ Apps should define an asset class to hold configuration information for the app.
|
|
|
60
60
|
|
|
61
61
|
.. _app-structure-app-init:
|
|
62
62
|
|
|
63
|
-
App
|
|
63
|
+
App Initialization
|
|
64
64
|
~~~~~~~~~~~~~~~~~~
|
|
65
65
|
|
|
66
66
|
.. literalinclude:: ../../tests/example_app/src/app.py
|
|
@@ -74,25 +74,111 @@ This is how you initialize the basic :class:`~soar_sdk.app.App` instance. The ap
|
|
|
74
74
|
|
|
75
75
|
.. _app-structure-actions-def:
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
Action Definitions
|
|
78
|
+
~~~~~~~~~~~~~~~~~~
|
|
79
|
+
|
|
80
|
+
Actions are defined as standalone functions, with a few important rules and recommendations.
|
|
81
|
+
|
|
82
|
+
Action Metadata
|
|
83
|
+
^^^^^^^^^^^^^^^
|
|
84
|
+
|
|
85
|
+
Action definition carry with them important metadata which is used by the Splunk SOAR platform to present the action in the UI, and to generate the app's manifest. Often, this metadata can be derived automatically from the action function's signature:
|
|
86
|
+
|
|
87
|
+
- The action's "identifier" is, by default, the name of the action function (e.g. ``my_action``).
|
|
88
|
+
- The action's "name" is, by default, the action function's name with spaces instead of underscores (e.g. ``my action``).
|
|
89
|
+
- The action's "description" is, by default, the action function's docstring.
|
|
90
|
+
- The action's "type" is, by default, ``generic`` unless the action is one of the reserved names like ``test connectivity`` or ``on poll``.
|
|
91
|
+
|
|
92
|
+
.. note::
|
|
93
|
+
By convention, action names should be lowercase, with 2-3 words. Keep action names short but descriptive, and avoid using the name of the app or external service in action names. Where feasible, it's recommended to consider reusing action names across different apps (e.g. ``get email``) to provide a more consistent user experience.
|
|
94
|
+
|
|
95
|
+
.. _app-structure-actions-args:
|
|
96
|
+
|
|
97
|
+
Action Arguments
|
|
98
|
+
^^^^^^^^^^^^^^^^
|
|
79
99
|
|
|
80
|
-
action
|
|
100
|
+
There is a magic element, similar to `pytest fixtures <https://docs.pytest.org/en/stable/how-to/fixtures.html#requesting-fixtures>`_, in the action arguments. The type hints for the argument definitions of an action function are critical to this mechanism. The rules are as follows:
|
|
101
|
+
|
|
102
|
+
- The first positional argument of an action function must be the ``params`` argument, and its type hint must be a `Pydantic model <https://docs.pydantic.dev/1.10/usage/models/#basic-model-usage>`_ inheriting from :class:`~soar_sdk.params.Params`. The position and type of this argument are required. The name ``params`` is a convention, but not strictly required.
|
|
103
|
+
- If an action function has any argument named ``soar``, at runtime the SDK will provide an instance of a :class:`~soar_sdk.abstract.SOARClient` implementation as that argument, which is already authenticated with Splunk SOAR. The type hint for this argument should be :class:`~soar_sdk.abstract.SOARClient`.
|
|
104
|
+
- If an action function has any argument named ``asset``, at runtime the SDK will provide an instance of the app's asset class, populated with the asset configuration for the current action run. The type hint for this argument should be the app's asset class.
|
|
105
|
+
|
|
106
|
+
.. note::
|
|
107
|
+
The special actions which define their own decorators have stricter rules about the type of the ``params`` argument. For example, the ``on poll`` action must take an :class:`~soar_sdk.params.OnPollParams` instance as its ``params`` argument, and ``test connectivity`` must take no ``params`` argument at all.
|
|
108
|
+
|
|
109
|
+
.. _app-structure-action-returns:
|
|
110
|
+
|
|
111
|
+
Action Returns
|
|
81
112
|
^^^^^^^^^^^^^^
|
|
82
113
|
|
|
83
|
-
|
|
114
|
+
An action's return type annotation is critical for the Splunk SOAR platform to understand, via datapaths, what an action's output looks like. In practice, this means that you must define a class inheriting from :class:`~soar_sdk.action_results.ActionOutput` to represent the action's output, and then return an instance of that class from your action function:
|
|
84
115
|
|
|
85
|
-
|
|
86
|
-
- ``soar`` - Optional, an instance of the :class:`~soar_sdk.abstract.SOARClient` implementation providing APIs for interacting with the Splunk SOAR platform.
|
|
87
|
-
- ``asset`` - Optional, an instance of the app's asset class, populated with the asset configuration for the current action run.
|
|
116
|
+
.. code-block:: python
|
|
88
117
|
|
|
89
|
-
|
|
118
|
+
from soar_sdk.action_results import ActionOutput
|
|
90
119
|
|
|
120
|
+
class MyActionOutput(ActionOutput):
|
|
121
|
+
field1: str
|
|
122
|
+
field2: int
|
|
91
123
|
|
|
92
|
-
|
|
124
|
+
@app.action()
|
|
125
|
+
def my_action(params: MyActionParams) -> MyActionOutput:
|
|
126
|
+
# action logic here
|
|
127
|
+
return MyActionOutput(field1="value", field2=42)
|
|
93
128
|
|
|
94
|
-
|
|
95
|
-
|
|
129
|
+
Advanced Return Types
|
|
130
|
+
*********************
|
|
131
|
+
|
|
132
|
+
For more advanced use cases, an action's return type can be a ``list``, ``Iterator``, or ``AsyncGenerator`` that yields multiple :class:`~soar_sdk.action_results.ActionOutput` objects:
|
|
133
|
+
|
|
134
|
+
.. tab-set::
|
|
135
|
+
.. tab-item:: ``list``
|
|
136
|
+
|
|
137
|
+
.. code-block:: python
|
|
138
|
+
|
|
139
|
+
@app.action()
|
|
140
|
+
def my_action_list(params: MyActionParams) -> list[MyActionOutput]:
|
|
141
|
+
# action logic here
|
|
142
|
+
return [
|
|
143
|
+
MyActionOutput(field1="value1", field2=1),
|
|
144
|
+
MyActionOutput(field1="value2", field2=2)
|
|
145
|
+
]
|
|
146
|
+
|
|
147
|
+
.. tab-item:: ``Iterator``
|
|
148
|
+
|
|
149
|
+
.. code-block:: python
|
|
150
|
+
|
|
151
|
+
from typing import Iterator
|
|
152
|
+
|
|
153
|
+
@app.action()
|
|
154
|
+
def my_action_iterator(params: MyActionParams) -> Iterator[MyActionOutput]:
|
|
155
|
+
# action logic here
|
|
156
|
+
yield MyActionOutput(field1="value1", field2=1)
|
|
157
|
+
yield MyActionOutput(field1="value2", field2=2)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
.. tab-item:: ``AsyncGenerator``
|
|
161
|
+
|
|
162
|
+
.. code-block:: python
|
|
163
|
+
|
|
164
|
+
from typing import AsyncGenerator
|
|
165
|
+
|
|
166
|
+
@app.action()
|
|
167
|
+
async def my_action_async_generator(
|
|
168
|
+
params: MyActionParams,
|
|
169
|
+
asset: Asset,
|
|
170
|
+
) -> AsyncGenerator[MyActionOutput]:
|
|
171
|
+
async with client = httpx.AsyncClient() as client:
|
|
172
|
+
async for i in range(10):
|
|
173
|
+
response = await client.get(
|
|
174
|
+
f"{asset.base_url}/data",
|
|
175
|
+
params={"page": i}
|
|
176
|
+
)
|
|
177
|
+
yield MyActionOutput(**response.json())
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
``test connectivity`` Action
|
|
181
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
96
182
|
|
|
97
183
|
.. literalinclude:: ../../tests/example_app/src/app.py
|
|
98
184
|
:caption: Test connectivity action definition
|
|
@@ -100,7 +186,7 @@ test connectivity action
|
|
|
100
186
|
:lineno-match:
|
|
101
187
|
:pyobject: test_connectivity
|
|
102
188
|
|
|
103
|
-
All apps must register exactly one ``
|
|
189
|
+
All apps must register exactly one ``test connectivity`` action in order to be considered valid by Splunk SOAR. This action takes no parameters, and is used to verify that the app and its associated asset configuration are working correctly. Running ``test connectivity`` on the Splunk SOAR platform should answer the questions:
|
|
104
190
|
|
|
105
191
|
- Can the app connect to the external service?
|
|
106
192
|
- Can the app authenticate with the external service?
|
|
@@ -108,8 +194,8 @@ All apps must register exactly one ``test_connectivity`` action in order to be c
|
|
|
108
194
|
|
|
109
195
|
A successful ``test connectivity`` action should return ``None``, and a failure should raise an :class:`~soar_sdk.exceptions.ActionFailure` with a descriptive error message.
|
|
110
196
|
|
|
111
|
-
on poll
|
|
112
|
-
|
|
197
|
+
``on poll`` Action
|
|
198
|
+
^^^^^^^^^^^^^^^^^^
|
|
113
199
|
|
|
114
200
|
.. literalinclude:: ../../tests/example_app/src/app.py
|
|
115
201
|
:caption: on poll action definition
|
|
@@ -119,7 +205,7 @@ on poll action
|
|
|
119
205
|
|
|
120
206
|
``on poll`` is another special action that apps may choose to implement. This action always takes an :class:`~soar_sdk.params.OnPollParams` instance as its parameter. If defined, this action will be called in order to ingest new data into the Splunk Splunk SOAR platform. The action should yield :class:`~soar_sdk.models.container.Container` and/or :class:`~soar_sdk.models.artifact.Artifact` instances representing the new data to be ingested. The SDK will handle actually creating the containers and artifacts in the platform.
|
|
121
207
|
|
|
122
|
-
|
|
208
|
+
Generic Action
|
|
123
209
|
^^^^^^^^^^^^^^
|
|
124
210
|
|
|
125
211
|
.. literalinclude:: ../../tests/example_app/src/app.py
|
|
@@ -134,7 +220,7 @@ We create an action by decorating a function with the ``app.action`` decorator.
|
|
|
134
220
|
is ``generic``, so usually you will not have to provide this argument for the decorator. This is not the
|
|
135
221
|
case for the ``test`` action type though, so we provide this type here explicitly.
|
|
136
222
|
|
|
137
|
-
|
|
223
|
+
Custom Actions
|
|
138
224
|
^^^^^^^^^^^^^^
|
|
139
225
|
|
|
140
226
|
Actions can be registered one of two ways:
|
|
@@ -166,7 +252,7 @@ The two methods are functionally equivalent. The decorator method is often more
|
|
|
166
252
|
|
|
167
253
|
.. _app-structure-app-cli:
|
|
168
254
|
|
|
169
|
-
App CLI
|
|
255
|
+
App CLI Invocation
|
|
170
256
|
~~~~~~~~~~~~~~~~~~
|
|
171
257
|
|
|
172
258
|
.. literalinclude:: ../../tests/example_app/src/app.py
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
.. _cli_reference:
|
|
2
|
+
|
|
3
|
+
CLI Reference
|
|
4
|
+
=============
|
|
5
|
+
|
|
6
|
+
The ``soarapps`` command-line tool is the main interface for working with Splunk SOAR apps from the command line. It provides commands for creating, building, and managing apps.
|
|
7
|
+
|
|
8
|
+
.. typer:: soar_sdk.cli.cli.app
|
|
9
|
+
:prog: soarapps
|
|
10
|
+
:width: 80
|
|
11
|
+
:preferred: text
|
|
12
|
+
:show-nested:
|
|
13
|
+
:make-sections:
|
|
14
|
+
|
|
15
|
+
App CLI
|
|
16
|
+
-------
|
|
17
|
+
|
|
18
|
+
The :class:`~soar_sdk.app.App` class automatically generates a command-line interface (CLI) for your app. This CLI can be used to run actions (and verify their behavior) from the command line.
|
|
19
|
+
|
|
20
|
+
.. code-block:: console
|
|
21
|
+
|
|
22
|
+
$ python src/app.py --help
|
|
23
|
+
usage: app.py [-h] [--soar-url SOAR_URL] [--soar-user SOAR_USER] [--soar-password SOAR_PASSWORD] {action,webhook} ...
|
|
24
|
+
|
|
25
|
+
positional arguments:
|
|
26
|
+
{action,webhook}
|
|
27
|
+
action Run an action
|
|
28
|
+
webhook Invoke a webhook handler
|
|
29
|
+
|
|
30
|
+
options:
|
|
31
|
+
-h, --help show this help message and exit
|
|
32
|
+
--soar-url SOAR_URL SOAR URL to connect to. Can be provided via PHANTOM_BASE_URL environment variable as well.
|
|
33
|
+
--soar-user SOAR_USER
|
|
34
|
+
Username to connect to SOAR instance. Can be provided via PHANTOM_USER environment variable as well
|
|
35
|
+
--soar-password SOAR_PASSWORD
|
|
36
|
+
Password to connect to SOAR instance. Can be provided via PHANTOM_PASSWORD environment variable as well
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
You can run any action defined in your app by using the ``action`` command. For example:
|
|
40
|
+
|
|
41
|
+
.. code-block:: console
|
|
42
|
+
|
|
43
|
+
$ python src/app.py action my-action --help
|
|
44
|
+
usage: app.py action my-action [-h] -p PARAMS_FILE -a ASSET_FILE
|
|
45
|
+
|
|
46
|
+
optional arguments:
|
|
47
|
+
-h, --help show this help message and exit
|
|
48
|
+
-p PARAMS_FILE, --params-file PARAMS_FILE
|
|
49
|
+
JSON file containing action parameters
|
|
50
|
+
-a ASSET_FILE, --asset-file ASSET_FILE
|
|
51
|
+
JSON file containing asset configuration
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Defining Your App's Asset Configuration
|
|
2
|
+
=======================================
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
Much of the functionality of a Splunk SOAR app depends on its ability to connect to external systems. This is done using an asset configuration, which provides the necessary connection details and credentials.
|
|
6
|
+
|
|
7
|
+
Like much of the definitions for objects in a Splunk SOAR app, the asset configuration is defined using `Pydantic models <https://docs.pydantic.dev/1.10/usage/models/#basic-model-usage>`_. The power of Pydantic models allows you to define complex data structures with validation and serialization capabilities, in a way where your code editor will be able to provide autocompletions and type checking.
|
|
8
|
+
|
|
9
|
+
.. note::
|
|
10
|
+
Users familiar with the ``BaseConnector`` style of Splunk SOAR apps may remember defining asset configuration with JSON. The Splunk SOAR SDK prefers to define all configuration in Python, and generate the JSON schema automatically. This ensures that the code and configuration are always in sync, and provides developers with significantly more useful editor support.
|
|
11
|
+
|
|
12
|
+
In the case of assets, these models must be subclasses of :class:`~soar_sdk.app.Asset`. An example Asset definition looks something like this:
|
|
13
|
+
|
|
14
|
+
.. literalinclude:: ../../tests/example_app/src/app.py
|
|
15
|
+
:caption: Asset definition
|
|
16
|
+
:language: python
|
|
17
|
+
:lineno-match:
|
|
18
|
+
:pyobject: Asset
|
|
19
|
+
|
|
20
|
+
.. seealso::
|
|
21
|
+
|
|
22
|
+
For more information on how to define an asset configuration, see the :ref:`App Structure <app-structure-asset-def>` documentation.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
Finally, in order to register the asset configuration with the app, it must be provided to the :class:`~soar_sdk.app.App` instance as the ``asset_cls`` parameter. For example::
|
|
26
|
+
|
|
27
|
+
app = App(
|
|
28
|
+
name="My App",
|
|
29
|
+
description="An example app",
|
|
30
|
+
version="1.0.0",
|
|
31
|
+
asset_cls=Asset, # <--- Asset class provided here
|
|
32
|
+
)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
Creating Your First Actions
|
|
2
|
+
===========================
|
|
3
|
+
|
|
4
|
+
All actions are defined as standalone functions, which are then registered with the :class:`~soar_sdk.app.App` object. Further, all apps are expected to implement a special ``test connectivity`` action, which is used to verify that the app can connect and authenticate to its external service.
|
|
5
|
+
|
|
6
|
+
The ``test connectivity`` Action
|
|
7
|
+
--------------------------------
|
|
8
|
+
|
|
9
|
+
Every app must implement a ``test connectivity`` action. This action takes no parameters, and is used to verify that the app and its associated asset configuration are working correctly. Running ``test connectivity`` on the Splunk SOAR platform should answer the questions:
|
|
10
|
+
|
|
11
|
+
- Can the app connect to the external service?
|
|
12
|
+
- Can the app authenticate with the external service?
|
|
13
|
+
- Does the app have the necessary permissions to perform its actions?
|
|
14
|
+
|
|
15
|
+
For example:
|
|
16
|
+
|
|
17
|
+
.. code-block:: python
|
|
18
|
+
|
|
19
|
+
@app.test_connectivity()
|
|
20
|
+
def test_connectivity(asset: Asset) -> None:
|
|
21
|
+
logger.info("Testing connectivity")
|
|
22
|
+
|
|
23
|
+
with httpx.Client() as client:
|
|
24
|
+
response = client.get("https://example.com/api/health", headers={
|
|
25
|
+
"Authorization": f"Bearer {asset.api_token}"
|
|
26
|
+
})
|
|
27
|
+
if not response.ok:
|
|
28
|
+
raise ActionFailure(
|
|
29
|
+
f"Connectivity test failed with status code {response.status_code}"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
logger.info("Connectivity test succeeded")
|
|
33
|
+
|
|
34
|
+
Your First Action
|
|
35
|
+
-----------------
|
|
36
|
+
|
|
37
|
+
Actions can be registered in multiple ways, with advantages and trade-offs to each. For a smaller app, the easiest method is to use the :func:`~soar_sdk.app.App.action` decorator directly on a function.
|
|
38
|
+
|
|
39
|
+
.. seealso::
|
|
40
|
+
|
|
41
|
+
See :ref:`Defining actions <app-structure-actions-def>` and/or :ref:`Action API Reference <api_ref_key_methods_label>` for more information.
|
|
42
|
+
|
|
43
|
+
The simplest action to create would look like this::
|
|
44
|
+
|
|
45
|
+
@app.action()
|
|
46
|
+
def my_action(params: Params, asset: BaseAsset) -> ActionOutput:
|
|
47
|
+
"""This is the first custom action in the app. It doesn't really do anything yet."""
|
|
48
|
+
return ActionOutput()
|
|
49
|
+
|
|
50
|
+
Let's break down this example to explain what happens here.
|
|
51
|
+
|
|
52
|
+
:func:`~soar_sdk.app.App.action` Decorator
|
|
53
|
+
------------------------------------------
|
|
54
|
+
|
|
55
|
+
.. code-block:: python
|
|
56
|
+
|
|
57
|
+
@app.action()
|
|
58
|
+
def my_action(...):
|
|
59
|
+
|
|
60
|
+
The decorator registers new action functions against :class:`~soar_sdk.app.App` instances. It is responsible for many things related to running the app under the hood. Here are some things it takes care of:
|
|
61
|
+
|
|
62
|
+
- registers new action functions, so they are invoked when running the app in Splunk SOAR platform
|
|
63
|
+
- sets the configuration values for the action (which can be defined by providing extra parameters to the decorator)
|
|
64
|
+
- ensures that the action name (by default, derived from the function name) is unique within the app
|
|
65
|
+
- checks if the action params are provided, valid and of the proper type
|
|
66
|
+
- ensures that the action output type is provided via return type annotation, and is valid
|
|
67
|
+
- inspects action argument types and validates them
|
|
68
|
+
|
|
69
|
+
.. seealso::
|
|
70
|
+
|
|
71
|
+
For more information about action registration, see the :ref:`App structure <app-structure-actions-def>` or :ref:`API Reference <api_ref_key_methods_label>` docs.
|
|
72
|
+
|
|
73
|
+
The Action Declaration
|
|
74
|
+
----------------------
|
|
75
|
+
|
|
76
|
+
.. code-block:: python
|
|
77
|
+
|
|
78
|
+
def my_action(params: Params, asset: BaseAsset) -> ActionOutput:
|
|
79
|
+
|
|
80
|
+
``my_action`` is the identifier of the action, and is used to derive the action's name (``my action``). This name will be used in the Splunk SOAR platform UI, and will be added to the app's generated manifest at packaging time.
|
|
81
|
+
|
|
82
|
+
Each action may accept and define ``params`` and ``asset`` arguments with proper type hints.
|
|
83
|
+
|
|
84
|
+
The ``params`` argument should always be the first argument, and of a type inherited from :class:`~soar_sdk.params.Params`. If an action takes no parameters, it's fine to use the ``Params`` base class here.
|
|
85
|
+
|
|
86
|
+
.. seealso::
|
|
87
|
+
|
|
88
|
+
Read more on defining action params in the :ref:`API Reference <action-param-label>` or :ref:`App structure <app-structure-actions-def>` docs.
|
|
89
|
+
|
|
90
|
+
The ``asset`` argument contains an instance of the app's asset configuration. It should be the same type that is specified as the ``asset_cls`` of the app.
|
|
91
|
+
|
|
92
|
+
Actions must have a return type that resolves to a type which extends from :class:`~soar_sdk.action_results.ActionOutput`. This is discussed further in the :ref:`Action Outputs <action-output-label>` and :ref:`App structure <app-structure-actions-def>` docs. The return type must be hinted.
|
|
93
|
+
|
|
94
|
+
The Action Docstring
|
|
95
|
+
--------------------
|
|
96
|
+
|
|
97
|
+
.. code-block:: python
|
|
98
|
+
|
|
99
|
+
"""This is the first custom action in the app. It doesn't really do anything yet."""
|
|
100
|
+
|
|
101
|
+
All actions should have a docstring. Beyond the general best practice it represents, the docstring is (by default) used by the SDK to generate the action description for the app documentation in Splunk SOAR.
|
|
102
|
+
|
|
103
|
+
The description should be kept short and simple, explaining what the action does.
|
|
104
|
+
|
|
105
|
+
The Action Result
|
|
106
|
+
-----------------
|
|
107
|
+
|
|
108
|
+
.. code-block:: python
|
|
109
|
+
|
|
110
|
+
return ActionOutput()
|
|
111
|
+
|
|
112
|
+
Each successful action run must return at least one action result.
|
|
113
|
+
Actions can fail gracefully by raising an :class:`~soar_sdk.exceptions.ActionFailure` exception. Other exceptions will be treated as unexpected errors.
|
|
114
|
+
|
|
115
|
+
The given example action simply returns the :class:`~soar_sdk.action_results.ActionOutput` base class, as it does not yet generate any results.
|
|
116
|
+
|
|
117
|
+
.. seealso::
|
|
118
|
+
|
|
119
|
+
Read more on action results and outputs in the :ref:`API Reference <action-output-label>` or :ref:`App structure <app-structure-action-returns>` docs.
|